Wie funktioniert die gcc `__thread` Arbeit?
Wie ist __thread
im gcc implementiert? Ist es einfach nur ein wrapper über pthread_getspecific
und pthread_setspecific
?
Mit meinem Programm, das mit der posix-API für TLS, ich bin ein bisschen enttäuscht, jetzt zu sehen, dass 30% meiner Programm-Laufzeit ausgegeben wird, auf pthread_getspecific
. Ich rief Sie auf den Eintrag, der jede Funktion aufrufen, muss die Ressource. Der compiler scheint nicht zu optimieren, aus pthread_getspecific
nach dem inlining-Optimierung. So nach und nach die Funktionen sind inline code ist im Grunde genommen das suchen nach der richtigen TLS Zeiger wieder und wieder die gleichen Zeiger zurückgegeben.
Wird __thread
helfen mir in dieser situation? Ich weiß, dass es thread_local
in C11, aber der gcc hab ich nicht unterstützen es noch. (Aber jetzt sehe ich, dass mein gcc unterstützt _Thread_local
einfach nicht das makro.)
Ich weiß, ich kann es einfach testen und sehen. Aber ich habe woanders geht jetzt, und ich würde gerne wissen, besser auf eine Funktion, bevor ich den Versuch einer ganz groß schreiben.
__thread
anders implementiert auf unterschiedlichen Plattformen, auf einige (du nicht sagen Sie uns was Sie Programmieren, für), umgesetzt werden könnte mitpthread_getspecific
.- Bitte geben Sie uns mehr Informationen! Ich würde wirklich gerne um Ihr problem zu lösen aber jetzt weiß ich nicht genug über das, was Plattform, die Sie verwenden / wie Sie Ihren code kompilieren zu können, geben Sie eine Antwort auf die Frage, wie man die thread-lokalen Speicher besser.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Letzten GCC, z.B. GCC 5 unterstützen C11 und seine
thread_local
(wenn Sie kompilieren mit z.B.gcc -std=c11
). Als FUZxxl kommentiert, Sie könnte verwenden (anstelle von C11thread_local
) die__thread
Qualifizierer unterstützt von älteren GCC-Versionen. Lesen Sie über Thread Local Storage.pthread_getspecific
ist in der Tat Recht langsam (es ist in der POSIX-Bibliothek, so wird nicht von GCC, sondern z.B. durch GNU-glibc oder musl-libc) da es sich um einen Aufruf der Funktion. Mitthread_local
Variablen wird sehr wahrscheinlich schneller.Blick in den Quellcode von MUSL ist
thread/pthread_getspecific.c
- Dateiein Beispiel für die Umsetzung. Lesen diese Antwort zu einer verwandten Frage.
Sowie
_thread
&thread_local
sind (oft) nicht auf Magische Weise übersetzt, um Anrufe zupthread_getspecific
. Sie beinhalten meist eine bestimmte Adresse-Modus und/oder registrieren (details sind die Umsetzung von spezifischen, im Zusammenhang mit der ABI; auf Linux, ich denke mal, dass da x86-64 hat mehr Register & Adresse Modi, die Implementierung von TLS ist schneller als auf i386), mit Hilfe von der compiler, die linker und die runtime-system. Es könnte passieren, im Gegenteil, dass einige Implementierungen vonpthread_getspecific
sind durch eine internethread_local
Variablen (in Ihrer Implementierung von POSIX-threads).Als ein Beispiel und kompilieren Sie den folgenden code
GCC verwenden 5.2 (auf Debian/Sid) mit
gcc -m32 -S -O2 -fverbose-asm
gibt den folgenden code fürget_data
mit TLS:folgenden code und den von
get_by_key
mit einem expliziten Aufruf zupthread_getspecific
:Daher die Verwendung von TLS mit
__thread
(oderthread_local
im C11) sollte wohl deutlich schneller sein alspthread_getspecific
(Vermeidung des Overheads von einem Anruf).Beachten Sie, dass
thread_local
ist ein Komfort-makro definiert in<threads.h>
(a C11 standard-header).__thread
ist ein pre-C11-Erweiterung von gcc, die den gleichen semantischen als C11 ist_Thread_local
, in der Tat ist es garantiert ein bisschen mehr als_Thread_local
.pthread_getspecific
ist nicht notwendigerweise eine Funktion aufrufen, kann es als makro implementiert.__thread
und_Thread_local
(d.h. integrierte TLS) implementiert. Eine Implementierung konnte sehr gut mitpthread_getspecific
undpthread_setspecific
zu implementieren, aber das ist nicht der Fall auf dem üblichen UNIX-ähnliche Betriebssysteme.%fs
für i386,%gs
für amd64). Der Geschwindigkeitsunterschied ist vernachlässigbar.gcc
__thread
hat genau die gleichen semantischen als C11 ist_Thread_local
. Sie sagen uns nicht, welche Plattform Sie Programmieren, für als die details der Implementierung variieren zwischen den Plattformen. Zum Beispiel auf x86 Linux, gcc kompilieren sollte der Zugriff auf thread-lokale Variablen, die als Speicher-Anweisungen mit einem%fs
- segment-Präfix anstelle eines Aufrufspthread_getspecific
.%fp
segment-register wird eingestellt, um einen nicht-null-Basis-Adresse, die Punkte der thread thread-lokale Daten. Ich kann dir nicht sagen, ob gcc kann dies auf Ihrer Plattform, wie Sie nicht geben mir genug Informationen. Könnten Sie auch mir die gcc-version, der Aufruf von gcc und Montage-Ausgänge (benutzen Sie die-S
Schalter)?__thread
jetzt.__thread
Variablen ohne Berufung aufpthread_getspecific
. Entweder ein anderer Teil des Codes ruftpthread_getspecific
oder etwas unheimliches passiert.pthread_getspecific
überhaupt. Ich denke, die Anrufe kommen von woanders.%gs
relativen Zugänge in der Erwägung, dass es generieren soll%fs
relative zugreift. Wie rufen Sie den gcc?pthread_getspecific
in meinem ursprünglichen Programm. Deshalb ist meine zweite Absatz ist es. Werde ich Bearbeiten, meine Frage um Verwirrung zu vermeiden.__thread
geben Sie eine anständige Leistung zu erhöhen.