2013-01-15 19 views
16

Opracowujemy aplikację opartą na sieci C/S, stwierdziliśmy, że istnieje zbyt wiele blokad dodających do std :: map, że wydajność serwera stała się zła.Czy możliwe jest zaimplementowanie mapy wolnej od blokady w C++

Zastanawiam się, czy możliwe jest wdrożenie mapy bez blokady, jeśli tak, w jaki sposób? Czy jest tam jakiś kod open source?

EDYTOWANIE: Aktualnie używamy std :: map do przechowywania informacji o gniazdach, zrobiliśmy enkapsulację w oparciu o opis pliku gniazda w celu włączenia innych niezbędnych informacji, takich jak adres IP, port, typ gniazda, tcp lub udp, itp. .

aby Podsumowując, mamy globalną mapę mówią, że to

map<int fileDescriptor, socketInfor*> SocketsMap, 

następnie każdy wątek, który jest używany do przesyłania danych musi mieć dostęp SocketsMap, a oni musieli dodać muteksu przed przeczytaniem od SocketsMap lub pisząc do SocketsMap , więc poziom współbieżności całej aplikacji znacznie spadłby z powodu s o wiele blokad dodawania do SocketsMap.

Aby uniknąć problemu z poziomem współbieżności, mamy dwa rozwiązania: 1. przechowuj każdy socketInfor * oddzielnie 2. używaj jakiejś mapy wolnej od blokady.

Chciałbym znaleźć jakieś wolne mapie zamka, ponieważ kody zmiany wymagane przez tego rozwiązania są znacznie mniejsze niż w przypadku rozwiązania 1.

+0

@WhozCraig Podsumowując, mówi się w języku C++ i wyraźnie mówi ... Są to bardzo różne języki, szczególnie jeśli weźmiesz pod uwagę zmienne atomowe. –

+0

@AlexChamberlain doskonały punkt, sir. Podniosę link. – WhozCraig

+0

Jeśli potrzebujesz pojemnika asocjacyjnego, ale nie wymagasz zamawiania, może być łatwiej użyć skrótu typu 'std :: unordered_map'. Może być szybszy nawet przy obecnym zgrubnym blokowaniu (szczególnie, jeśli możesz przenosić dowolne kosztowne obliczenia haszowania poza zablokowaną częścią), ale podejrzewam, że czasami kosztowne ponowne szyfrowanie jest również łatwiejsze w obsłudze niż sporadyczne ponowne zrównoważenie, dla optymizmu. Wersja bez blokady. – Useless

Odpowiedz

14

Faktycznie istnieje sposób, choć nie wdrożyły to sam jest artykuł o lock free map using hazard pointers od wybitnego eksperta C++ Andrei Alexandrescu.

+0

Zobacz także http://libcds.sourceforge.net/ –

+0

Uwaga: wskaźniki zagrożeń są opatentowane, więc możesz nie być w stanie użyć tego w kodzie produkcyjnym. Czyż nie jest cudowne IPR? –

+0

Dzięki. Zmieniłem wpis, aby dodać więcej informacji, czy masz więcej sugestii? – Steve

1

Możesz zaimplementować mapę, używając optimistic design lub transactional memory.

To podejście jest szczególnie skuteczne, gdy szansa na dwie operacje jednoczesne adresowania mapy i jedna zmienia jej strukturę jest stosunkowo niewielka - i nie chcesz narzutów blokowania za każdym razem.

Jednak od czasu do czasu zdarza się kolizja i trzeba ją jakoś zmusić (zwykle cofając się do ostatniego stabilnego stanu i ponawiając operacje).

Jeśli twój sprzęt obsługuje wystarczająco dobre operacje atomowe - można to łatwo zrobić za pomocą Compare And Swap (CAS) - gdzie sam zmieniasz odniesienie (i kiedy zmieniasz mapę, pracujesz nad kopią mapy, a nie oryginałem, i ustaw ją jako podstawową tylko wtedy, gdy dokonasz zatwierdzenia).

2

HashMap byłby odpowiedni? Spójrz na Intel Threading Building Blocks, mają ciekawą współbieżną mapę. Nie jestem pewien, czy nie jest zablokowany, ale mam nadzieję, że interesuje Cię dobra wydajność wielowątkowości, a nie szczególnie w przypadku blokady.Ponadto można sprawdzić CityHash lib

EDIT:

Właściwie TBB za hash mapa nie jest zablokować wolne

1

jestem nikt zaskoczony wspomniał, ale Kliknij Cliff wdrożył czekać wolne hashmap in Java, który wierzę, że może być przeniesiony do C++,

2

Jeśli używasz C++ 11, można rzucić okiem na AtomicHashMap z facebook/folly

+0

To prawdopodobnie nie jest to, co OP chce. Mapa, do której prowadzi link, nie jest całkowicie pozbawiona zabezpieczeń. Z dokumentacji: AHArray jest stałym ciągłym blokiem komórek value_type. Po wpisaniu komórki klucz jest blokowany, podczas gdy reszta rekordu jest zapisywana jako . –

2

Tak, wdrożyliśmy Lock-Free Unordered Map (docs) w języku C++ przy użyciu koncepcji "listy rozdzielone uporządkowanymi". Jest to automatycznie rozwijany kontener i obsługuje miliony elementów w 64-bitowym CAS bez problemów ABA. Pod względem wydajności jest to beast (patrz strona 5). To było extensively tested z milionami losowych operacji.

+0

To wygląda pięknie. Jednak opiera się na klangu, który wydaje się być uszkodzony od wersji 3.4 (aktualnie jestem na 3.7). Nie można znaleźć pliku obejmującego system. Nie mam przepustowości do dalszych badań. – Nicole

Powiązane problemy