2011-12-13 13 views
14

teraz, że C++ jest dodanie thread_local przechowywanie jako cecha języka, zastanawiam się kilka rzeczy:Cena thread_local

  1. Jaki jest koszt thead_local prawdopodobne?
    • W pamięci?
    • Do operacji odczytu i zapisu?
  2. Związany z tym: w jaki sposób systemy operacyjne zazwyczaj to wdrażają? Wygląda na to, że wszystko, co zostanie zadeklarowane jako thread_local, musiałoby zostać przydzielone specyficznej dla wątku przestrzeni do przechowywania dla każdego utworzonego wątku.
+3

Największy koszt to łatwość konserwacji kodu. –

Odpowiedz

8

Miejsce do przechowywania: rozmiar zmiennej * liczba wątków lub ewentualnie (sizeof (var) + sizeof (var *)) * liczba wątków.

Istnieją dwa podstawowe sposoby realizacji pamięć lokalna wątku:

  1. Korzystanie jakiegoś wywołania systemowego, który pobiera informacje o aktualnym wątku jądra. Sloooow.

  2. Używanie jakiegoś wskaźnika, prawdopodobnie w rejestrze procesora, który jest ustawiony poprawnie przy każdym przełączeniu kontekstu wątku przez jądro - w tym samym czasie, co wszystkie inne rejestry. Tani.

Na platformach wywiadu, wariant 2 jest zwykle realizowany za pośrednictwem rejestru segmentów (FS lub GS, nie pamiętam). Zarówno GCC, jak i MSVC wspierają to. Czasy dostępu są zatem tak szybkie, jak w przypadku zmiennych globalnych.

Jest to również możliwe, ale nie widziałem go jeszcze w praktyce, aby było to realizowane za pośrednictwem istniejących funkcji bibliotecznych, takich jak pthread_getspecific. Wydajność byłaby wtedy równa 1. lub 2., a także narzut na bibliotekę. Należy pamiętać, że narzuty dla wersji 2. i biblioteki są wciąż dużo szybsze niż wywołanie jądra.

+0

Należy zauważyć, że program uruchamiający i dynamiczny linker systemu operacyjnego (dla bibliotek współużytkowanych/bibliotek DLL) wymagają specjalnej obsługi dla wariantu 2. Aby protokół TLS działał poprzez rejestr segmentów, wiele pracy wymaga pracy. Ale warto, ponieważ obciążenie związane ze stosowaniem zmiennej TLS jest wówczas nieistotne w porównaniu do normalnego globalnego. –

9

opis jak to działa na Linuksie przez Uli Drepper (opiekuna glibc) można znaleźć tutaj: www.akkadia.org/drepper/tls.pdf

Wymóg obsłużyć dynamicznie ładowane moduły itp uczynić cały mechanizm trochę zawiłe, co może częściowo wyjaśnia, dlaczego dokument waży 79 stron (!).

Zależnie od użycia pamięci każda zmienna wątku oczywiście potrzebuje własnej pamięci na wątek (chociaż w niektórych przypadkach można to zrobić leniwie w taki sposób, że miejsce jest przydzielane tylko po pierwszym uzyskaniu dostępu do zmiennej), a następnie istnieje kilka dodatkowych struktur danych, które są potrzebne w tabelach offsetowych itp.

Pod względem wydajności dodatkowy koszt dostępu do zmiennej TLS dotyczy głównie pobierania adresu zmiennej. W systemie x86 Linux rejestr GS jest używany jako początek do uzyskania identyfikatora wątku na serwerze x86-64 FS. Zwykle istnieje kilka dereferencji wskaźnika i wywołanie funkcji (__tls_get_addr) dla dynamicznie ładowanego kodu. Istnieje również koszt, że tworzenie nowego wątku jest wolniejsze, ponieważ implementacja musi alokować przestrzeń i ewentualnie inicjować wszystkie zmienne TLS (jeśli nie są wykonywane leniwie).

TLS jest łatwy do robienia niektórych starych wątków niebezpiecznych szablonów bez wątków (pomyśl o błędach), ale dla nowego kodu zaprojektowanego od początku dla świata wielowątkowego jest bardzo rzadko potrzebny.

+6

Nie zgadzam się z tym _ bardzo rzadko potrzebuję komentarza. TLS to bardzo prosty, czysty i szybki sposób na zmniejszenie rywalizacji między wątkami i poprawę wydajności poprzez unikanie powtarzających się wyszukiwań w wątku. –

Powiązane problemy