2017-10-16 26 views
7

İlk sürüm, bir değeri bellekten yerel bir değişkene taşıyarak bir optimizasyon yapar. İkinci versiyon yok.Derleyici neden bu döngünün her yinelemesi için bellekte bir üye değişkeni yazıyor?

Derleyicinin yine de localValue optimizasyonunu burada yapmayı seçebileceğini ve döngünün her yinelemesi için bellekten değeri okumayı ve yazmayı beklemeyi bekliyordum. Neden olmasın (V1 atom değildir) derleyici parçacığı konusunda endişelenmenize gerek yok

.L5: 
    movss xmm0, DWORD PTR [rax] 
    addss xmm0, DWORD PTR example[rip] 
    movss DWORD PTR [rax], xmm0 
    mulss xmm0, xmm1 
    movss DWORD PTR example[rip], xmm0 
    add rax, 4 
    cmp rax, rdx 
    jne .L5 

gibi:

.L4: 
    addss xmm0, DWORD PTR [rax] 
    movss DWORD PTR [rax], xmm0 
    mulss xmm0, xmm1 
    add rax, 4 
    cmp rax, rcx 
    jne .L4 

processSamples2 buna:

class Example 
{ 
    public: 
     void processSamples(float * x, int num) 
     { 
      float localValue = v1; 

      for (int i = 0; i < num; ++i) 
      { 
       x[i] = x[i] + localValue; 
       localValue = 0.5 * x[i]; 
      } 

      v1 = localValue; 
     } 

     void processSamples2(float * x, int num) 
     { 

      for (int i = 0; i < num; ++i) 
      { 
       x[i] = x[i] + v1; 
       v1 = 0.5 * x[i]; 
      } 

     } 

    float v1; 
}; 

processSamples böyle kodlamak araya . Sadece bu değere bakacak başka bir şey olmayacak mı ve devam edip, döngü dönerken bir kayıtta tutmayacak mıdır?

Tüm kurulum ve seçim yapabileceğiniz derleyiciler arasından seçim için https://godbolt.org/g/RiF3B4'a bakın!

+0

Bağladığınız örnekte başka bir sorun var. İlk kullanıldığında 'v1 'başlatılmamış. Bu UB ve gcc ve argo optimizasyon zamanında tuhaf şeyler yapmak için neden olur. –

+0

Oh evet - adil nokta - gerçek bir kod değil, sadece ilgilendiğim problemi göstermek istedim ve v1 için başlangıç ​​noktası gerçekten önemli değildi. Asıl kod biraz daha rafine. – JCx

+0

ilginç ve dikkatli okuma: https://blog.regehr.org/archives/759 –

cevap

11

aliasing nedeniyle: v1 üye değişkendir ve x noktasında olabilir. Bu nedenle, x öğelerine yapılan yazılardan biri v1 değiştirebilir.

C99'da, derleyiciyi işlev kapsamında olan başka bir takma ad olduğunu bilmemesi için işaretçi türü işlev argümanı üzerindeki kısıtlama anahtar sözcüğünü kullanabilirsiniz. Standart olmasa da bazı C++ derleyicileri de destekliyor. (İçindekilerimden birini kopyalayın.)

+0

Wow - tamam - bu durumda olmayacak bir şey var mı? – JCx

+2

@JCx: C99'da, derleyiciyi işlev kapsamında olan başka bir takma ad olduğunu bilmemesi için işaretçi türü işlev argümanında 'restrict' anahtar sözcüğünü kullanabilirsiniz. [Bazı C++ derleyicileri de bunu destekliyor] (standart olarak olmamasına rağmen, https://stackoverflow.com/questions/776283/what-does-the-restrict-keyword-mean-in-c#1965502). –

+2

Tamam - clang ile test edildi. Sıralı olarak kısıtla. Güzel :) – JCx

İlgili konular