簡體   English   中英

為什么編譯器會為此循環的每次迭代將成員變量寫入內存?

[英]Why does the compiler write a member variable to memory for each iteration of this loop?

第一個版本通過將值從內存移動到局部變量來進行優化。 第二個版本沒有。

我原以為編譯器可能會選擇在這里進行localValue優化,而不是在循環的每次迭代中從內存中讀取和寫入值。 為什么不呢?

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組裝成代碼如下:

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

processSamples2到此:

.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

因為編譯器不必擔心線程(v1不是原子的)。 難道不能只是假設沒有別的東西會看到這個值並繼續在循環旋轉時將它保存在寄存器中嗎?

有關完整程序集和各種編譯器可供選擇,請參閱https://godbolt.org/g/RiF3B4

由於別名v1是一個成員變量,可能是x指向它。 因此,對x元素的寫入之一可能會改變v1

在C99中,您可以在指針類型的函數參數上使用restrict關鍵字,以通知編譯器它不會對函數范圍內的任何其他內容進行別名。 一些C ++編譯器也支持它,盡管它不是標准的。 (復制自我的一條評論。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM