c – 为什么编译器会为此循环的每次迭代将成员变量写入内存?

c – 为什么编译器会为此循环的每次迭代将成员变量写入内存?,第1张

概述第一个版本通过将值从内存移动到局部变量来进行优化.第二个版本没有. 我原本期望编译器可能会选择在这里进行localValue优化,而不是在循环的每次迭代中从内存中读取和写入值.为什么不呢? class Example{ public: void processSamples(float * x, int num) { float 第一个版本通过将值从内存移动到局部变量来进行优化.第二个版本没有.

我原本期望编译器可能会选择在这里进行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],xmm1  movss DWORD PTR example[rip],xmm0  add rax,rdx  jne .L5

因为编译器不必担心线程(v1不是原子的).难道不能只是假设没有别的东西会看到这个值并继续在循环旋转时将它保存在寄存器中吗?

有关完整装配和一系列可供选择的编译器,请参阅https://godbolt.org/g/RiF3B4!

解决方法 因为 aliasing:v1是一个成员变量,它可能是x指向它.因此,对x元素的写入之一可能会改变v1.

在C99中,您可以在指针类型的函数参数上使用restrict关键字来通知编译器它不会对函数范围内的任何其他内容进行别名.一些C编译器也支持它,虽然它不是标准的.(根据我的一条评论复制.)

总结

以上是内存溢出为你收集整理的c – 为什么编译器会为此循环的每次迭代将成员变量写入内存?全部内容,希望文章能够帮你解决c – 为什么编译器会为此循环的每次迭代将成员变量写入内存?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1240729.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存