[32][Wydajność]

PYTANIA

Jaka jest najbardziej wydajna technika indeksowania danych?

Jak wszyscy wiemy, istnieją pewne techniki indeksowania danych, których używają dobrze znane aplikacje indeksujące, takie jak Lucene (dla java) lub Lucene.NET (dla .NET), MurMurHash, B + Tree itp. Dla obiektu bez Sql / Object Oriented Database (którą próbuję napisać / grać trochę w C#), jaką technikę sugerujesz? Czytałem o MurMurhash-2, a zwłaszcza komentarze v3 mówią, że Murmur jest bardzo szybki. Również Lucene.Net ma na ten temat dobre komentarze. Ale co z ich śladami pamięci w ogóle?

Czy jest jakieś wydajne rozwiązanie, które zużywa mniej miejsca (i oczywiście jeśli preferowane jest szybsze) niż Lucene lub Murmur? Czy powinienem napisać specjalną strukturę indeksu, aby uzyskać najlepsze wyniki? Jeśli spróbuję napisać własną, to czy istnieje jakakolwiek akceptowana skala dobrego indeksowania, coś w rodzaju 1% węzła danych lub 5% węzła danych? Każda przydatna wskazówka zostanie doceniona.

 ODPOWIEDZI

Myślę, że pomieszałeś niektóre rzeczy w swoim pytaniu. Lucene (nic nie wiem o Lucene.NET, ale przypuszczam, że jest tak samo) to biblioteka używana do analizy, dzielenia na tokeny i przechowywania dokumentów w celu późniejszego ich wyszukania i odzyskania. Lucene ma dość stary, ale skuteczny model, wykorzystuje odwrócone drzewa do wyszukiwania i wyszukiwania dokumentów. Bez dalszych szczegółów, wszystkie dokumenty są podzielone na tokeny (warunki), a dla każdego terminu jest utrzymywana struktura danych, która przechowuje wszystkie dokumenty zawierające dany termin. Jako strukturę danych można zastosować BTree, tablicę skrótów i w najnowszych ważnych wersjach możesz to zrobić , nawet podłącz własne struktury danych. BTree jest rodzajem struktury danych drzewa, która jest odpowiednia do pracy z dużymi fragmentami danych i często służy do przechowywania na dysku uporządkowanych struktur przypominających trele. W przypadku pamięci inne drzewa działają lepiej. Murmur hash, to rodzina funkcji hash używanych w tabeli hash. Implementacja tabeli skrótów nie jest ważna, może to być standardowa implementacja łańcuchowa lub bardziej zaawansowany schemat adresowania skrótów. Chodzi o to, że tabele skrótów pozwalają szybko uzyskać klucz z nieuporządkowanego zestawu kluczy i mogą odpowiadać na zadania takie jak: czy ten klucz jest częścią tego zestawu kluczy? jaka jest wartość związana z tym kluczem? Teraz wróć do głównego problemu. Masz jedną bibliotekę (Lucene), a do struktur danych obie struktury danych są używane w Lucene. Teraz widzisz, że na te pytania nie można odpowiedzieć, ponieważ nie są one porównywalne. Jednak w odniesieniu do twojego śladu i wydajności część pytania. Przede wszystkim musisz wiedzieć, jakie operacje musisz wdrożyć. Czy potrzebujesz tylko wartości dla klucza, czy też musisz znaleźć wszystkie elementy w zakresie? Innymi słowy, potrzebujesz zamówienia czy nie? Jeśli tak, to drzewo może pomóc. Jeśli tego nie zrobisz, zamiast tego można użyć szybszej tabeli skrótów. Czy masz dużo danych, które nie pasują do pamięci? Jeśli tak, pomogłoby rozwiązanie oparte na dysku (jak BTree). Jeśli Twoje dane mieszczą się w pamięci, użyj najszybszego rozwiązania w pamięci i użyj dysku tylko jako magazynu (o innej strukturze, o wiele prostszej).

Jak przyspieszyć przekazywanie wiadomości między węzłami obliczeniowymi?

Zajmuję się tworzeniem aplikacji rozproszonej, a ponieważ została zaprojektowana, podczas przetwarzania będzie mnóstwo komunikacji. Ponieważ komunikacja jest już tak szeroko rozłożona na cały proces, jak to możliwe, zastanawiam się, czy istnieją jakieś standardowe rozwiązania poprawiające wydajność warstwy przekazywania wiadomości w mojej aplikacji. Jakie zmiany / ulepszenia mogę zastosować do mojego kodu, aby skrócić czas wysyłania wiadomości? Za to, co jest tego warte, komunikuję się do 10 GB między 9 węzłami obliczeniowymi, a środowisko, którego używam, jest zaimplementowane w OpenMPI.

ODPOWIEDZI

Buforowanie rzeczy jest na ogół dobre, jeśli możesz, ale uważam, że jest nieco kruche, ponieważ jest to bardzo zależne od tego, jaka dokładnie jest twoja aplikacja. Kompresja danych to kolejna bardzo solidna sugestia, ale mam wrażenie, że oba te przyspieszenia będą względnie marginalne. Może nawet 2-5x, ale byłbym bardzo zaskoczony, gdyby byli szybsi. Przy założeniu, że czyste we / wy (zapis do / odczyt z pamięci) nie jest twoim ograniczającym czynnikiem (jeśli tak, prawdopodobnie nie będziesz dużo szybszy), zrobiłbym silną wtyczkę dla zeromq. Słowami twórców:

Wzięliśmy normalne gniazdo TCP, wstrzyknęliśmy mu mieszaninę radioaktywnych izotopów skradzionych z tajnego sowieckiego projektu badań atomowych, zbombardowaliśmy go promieniami kosmicznymi z 1950 roku i włożyliśmy w ręce uzależnionego od narkotyków autora komiksu ze źle ukrytym fetysz wyłupiastych mięśni spandeksowych. Tak, gniazda ØMQ to światowi superbohaterowie świata sieciowego.

Choć może to być trochę dramatyczne, gniazda zeromq są moim zdaniem jednym z najbardziej niesamowitych programów, jakie świat sieci komputerowych stworzył od kilku lat. Nie jestem pewien, czego używasz w tej chwili do przekazywania wiadomości, ale jeśli używasz czegoś tradycyjnego, takiego jak rabbitmq, możesz zobaczyć przyspieszenie wielu rzędów wielkości (osobiście zauważyłem około 500x, ale zależy dużo architektury). Sprawdź tutaj kilka podstawowych testów porównawczych.

Jeśli oczekujesz (lub stwierdzisz), że węzły żądają tych samych danych więcej niż raz, być może mógłbyś skorzystać ze strategii buforowania? Zwłaszcza tam, gdzie niektóre dane są wykorzystywane znacznie częściej niż inne, więc możesz kierować reklamy tylko na najczęściej używane informacje. Jeśli dane są zmienne, potrzebujesz również sposobu, aby potwierdzić, że nie uległy one zmianie od ostatniego żądania, które jest tańsze niż jego powtórzenie. Jest to dodatkowo skomplikowane, jeśli każdy węzeł ma swoją własną pamięć podręczną. W zależności od charakteru systemu i zadań możesz rozważyć dodanie węzła dedykowanego do udostępniania informacji między węzłami przetwarzającymi i zbudowanie pojedynczej pamięci podręcznej na tym węźle. Na przykład, kiedy może to być dobry pomysł, załóżmy, że pobieram niektóre dane ze zdalnego magazynu danych przez połączenie o niskiej przepustowości i mam pewne zadania wymagające tych danych, które są dystrybuowane wyłącznie między węzłami lokalnymi. Na pewno nie chcę, aby każdy węzeł żądał informacji osobno przez to połączenie o niskiej przepustowości, o które wcześniej mógł poprosić inny węzeł. Ponieważ moje lokalne operacje we / wy są znacznie tańsze niż moje operacje we / wy przez połączenie o niskiej przepustowości, mogę dodać węzeł między węzłami przetwarzającymi a zdalnym źródłem, który działa jak serwer pośredni. Ten węzeł pobierałby żądania od węzłów przetwarzających, komunikował się ze zdalnym magazynem danych i buforował często żądane dane, aby zminimalizować wykorzystanie tego połączenia o niskiej przepustowości. Podstawowe pojęcia, które mogą mieć zastosowanie w konkretnym przypadku, to:

* Wyeliminuj lub zmniejsz zbędne I / O;

* Skorzystaj z kompromisów między zużyciem pamięci a czasem obliczeniowym;

* Nie wszystkie wejścia / wyjścia są sobie równe.

Scikit Learn Regresja Logistyczna Wyciek pamięci

Jestem ciekawy, czy ktoś na to wpadł. Mam zestaw danych z około 350 tys. Próbek, każda z 4k rzadkimi funkcjami. Niski poziom wypełnienia wynosi około 0,5%. Dane są przechowywane w obiekcie scipy.sparse.csr.csr_matrix, z dtype = ‘numpy.float64’. Używam tego jako danych wejściowych do klasyfikatora regresji logistycznej sklearn. Dokumentacja wskazuje, że rzadkie macierze CSR są akceptowalnymi danymi wejściowymi dla tego klasyfikatora. Jednak, kiedy trenuję klasyfikator, mam bardzo niską wydajność pamięci; użycie pamięci przez mój proces eksploduje z ~ 150 MB, aby wypełnić całą dostępną pamięć, a następnie wszystko zatrzymuje się, gdy następuje zamiana pamięci na dysk. Czy ktoś wie, dlaczego ten klasyfikator może rozszerzyć macierz rzadką do macierzy gęstej? Obecnie używam domyślnych parametrów klasyfikatora w ramach zaktualizowanej dystrybucji anakody. Dzięki!

scipy .__ version__ = „0.14.0”

sklearn .__ version__ = „0.15.2”

Ok, skończyło się to sytuacją RTFM, chociaż w tym przypadku był to komunikat o błędzie RTF. Podczas uruchamiania tego nadal pojawiał się następujący błąd: DataConversionWarning: Wektor kolumnowy y został przekazany, gdy oczekiwano tablicy 1d. Proszę zmienić kształt. Zakładałem, że ponieważ miało to związek z wektorem docelowym, a ponieważ było to tylko ostrzeżenie, to po prostu po cichu zmieniłoby mój wektor docelowy na 1-D. Jednak gdy jawnie przekonwertowałem mój wektor docelowy na 1-D, moje problemy z pamięcią zniknęły. Najwyraźniej posiadanie wektora docelowego w niepoprawnej formie spowodowało, że zamienił on moje wektory wejściowe w gęste wektory z wektorów rzadkich. Wyciągnięta lekcja: postępuj zgodnie z zaleceniami, gdy sklearn „sugeruje”, że coś robisz.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *