SORU
28 EKİM 2012, Pazar


C 11: 4.8 `thread_local` Performans Ceza GCC?

GCC 4.8 draft changelog:

G şimdiC 11 thread_local anahtar sözcük; bu farklıdır uygular GNU __thread izin öncelikle anahtar kelime dinamik başlatma ve yıkım anlambilim. Ne yazık ki, bu destek başvurular için çalıştırma cezası olmayan fonksiyon-yerel gerektirir Eğer dinamik başlatma gerek varsa. thread_local bile değişkenler, kullanıcılar ile TLS değişkenler için __thread kullanmaya devam etmek isteyebilir yani statik başlatma anlambilim.

Hassas doğası ve kökeni çalıştırma cezası nedir?

Açıkçası destek olmayan fonksiyon-yerel thread_local değişkenleri yok edilmesi gerek bir iş parçacığı başlatma aşamasından önce giriş için her iş parçacığı ana (gibi bir statik başlatma aşaması için genel değişkenler), ama onlar bağlıyordum için bazı çalışma cezası bunun dışında mı?

Konuşma thread_local gcc yeni uygulama mimarisi nedir kabaca?

CEVAP
29 EKİM 2012, PAZARTESİ


(Yasal Uyarı: GCC iç hakkında çok şey bilmiyorum, bu da bir tahmin.)

thread_local dinamik başlatma 462819c taahhüt eklenir. Değişim biridir:

* semantics.c (finish_id_expression): Replace use of thread_local
variable with a call to its wrapper.

Çalıştırma cezası, thread_local değişken her referans bir işlev çağrısı olacak. Basit bir test çalışması ile kontrol edelim:

// 3.cpp
extern thread_local int tls;    
int main() {
    tls  = 37;   // line 6
    tls &= 11;   // line 7
    tls ^= 3;    // line 8
    return 0;
}

// 4.cpp

thread_local int tls = 42;

Derlenmiş*, biz görüyoruzhertls referans kullanımı tembel bir kez değişken başlatma _ZTW3tls, çağıran bir işlev olur:

00000000004005b0 <main>:
main():
  4005b0:   55                          push   rbp
  4005b1:   48 89 e5                    mov    rbp,rsp
  4005b4:   e8 26 00 00 00              call   4005df <_ZTW3tls>    // line 6
  4005b9:   8b 10                       mov    edx,DWORD PTR [rax]
  4005bb:   83 c2 25                    add    edx,0x25
  4005be:   89 10                       mov    DWORD PTR [rax],edx
  4005c0:   e8 1a 00 00 00              call   4005df <_ZTW3tls>    // line 7
  4005c5:   8b 10                       mov    edx,DWORD PTR [rax]
  4005c7:   83 e2 0b                    and    edx,0xb
  4005ca:   89 10                       mov    DWORD PTR [rax],edx
  4005cc:   e8 0e 00 00 00              call   4005df <_ZTW3tls>    // line 8
  4005d1:   8b 10                       mov    edx,DWORD PTR [rax]
  4005d3:   83 f2 03                    xor    edx,0x3
  4005d6:   89 10                       mov    DWORD PTR [rax],edx
  4005d8:   b8 00 00 00 00              mov    eax,0x0              // line 9
  4005dd:   5d                          pop    rbp
  4005de:   c3                          ret

00000000004005df <_ZTW3tls>:
_ZTW3tls():
  4005df:   55                          push   rbp
  4005e0:   48 89 e5                    mov    rbp,rsp
  4005e3:   b8 00 00 00 00              mov    eax,0x0
  4005e8:   48 85 c0                    test   rax,rax
  4005eb:   74 05                       je     4005f2 <_ZTW3tls 0x13>
  4005ed:   e8 0e fa bf ff              call   0 <tls> // initialize the TLS
  4005f2:   64 48 8b 14 25 00 00 00 00  mov    rdx,QWORD PTR fs:0x0
  4005fb:   48 c7 c0 fc ff ff ff        mov    rax,0xfffffffffffffffc
  400602:   48 01 d0                    add    rax,rdx
  400605:   5d                          pop    rbp
  400606:   c3                          ret

Bu ekstra sarıcı olmaz __thread sürümü ile karşılaştırın:

00000000004005b0 <main>:
main():
  4005b0:   55                          push   rbp
  4005b1:   48 89 e5                    mov    rbp,rsp
  4005b4:   48 c7 c0 fc ff ff ff        mov    rax,0xfffffffffffffffc // line 6
  4005bb:   64 8b 00                    mov    eax,DWORD PTR fs:[rax]
  4005be:   8d 50 25                    lea    edx,[rax 0x25]
  4005c1:   48 c7 c0 fc ff ff ff        mov    rax,0xfffffffffffffffc
  4005c8:   64 89 10                    mov    DWORD PTR fs:[rax],edx
  4005cb:   48 c7 c0 fc ff ff ff        mov    rax,0xfffffffffffffffc // line 7
  4005d2:   64 8b 00                    mov    eax,DWORD PTR fs:[rax]
  4005d5:   89 c2                       mov    edx,eax
  4005d7:   83 e2 0b                    and    edx,0xb
  4005da:   48 c7 c0 fc ff ff ff        mov    rax,0xfffffffffffffffc
  4005e1:   64 89 10                    mov    DWORD PTR fs:[rax],edx
  4005e4:   48 c7 c0 fc ff ff ff        mov    rax,0xfffffffffffffffc // line 8
  4005eb:   64 8b 00                    mov    eax,DWORD PTR fs:[rax]
  4005ee:   89 c2                       mov    edx,eax
  4005f0:   83 f2 03                    xor    edx,0x3
  4005f3:   48 c7 c0 fc ff ff ff        mov    rax,0xfffffffffffffffc
  4005fa:   64 89 10                    mov    DWORD PTR fs:[rax],edx
  4005fd:   b8 00 00 00 00              mov    eax,0x0                // line 9
  400602:   5d                          pop    rbp
  400603:   c3                          ret

Bu sarıcı thread_local Her durumda kullanmak için gerekli değildir. Bu decl2.c açığa çıkarılabilir. Sarıcı sadece oluşturulur:

  • değilfonksiyon-yerel ve,

    1. extern (yukarıda gösterilen örnek), ya da
    2. Bu tür önemsiz olmayan bir yıkıcı __thread değişkenler için izin verilmez)
    3. Tipi değişken sabit olmayan ifade Bir da __thread değişkenler için izin verilmez) tarafından başlatıldı.

Tüm diğer durumlarda, __thread ile aynı davranır. Bu, extern __thread bazı değişkenler olmadığı sürece, performans kaybı olmadan thread_local __thread tümünü değiştir anlamına gelir.


*: İnliner fonksiyon sınırı daha az fark edilebilir çünkü O0 ile derlenmiş. Eğer açarsak bile-O3 bu başlatma kontrolleri hala devam etmektedir.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • CNET

    CNET

    5 Mayıs 2006
  • jbignacio

    jbignacio

    13 Mart 2006
  • super1988guy

    super1988guy

    9 Aralık 2007