设置并检查 32 位变量

setting and checking a 32 bit variable

本文关键字:变量 检查 设置      更新时间:2023-10-16

我想知道在检查后设置一个 32 位变量是否会比仅仅设置它更快? 例如,变量 a 是 uint32

if( a != 0)
{
    a = 0;
}

a = 0;

代码将在循环中运行,它将运行多次,因此我想减少运行代码的时间。请注意,变量 a 大多数时候都是 0,因此问题可以缩短为检查 32 位变量或设置它是否更快。提前谢谢你!

编辑:感谢所有对这个问题发表评论的人,我创建了一个 for 循环并测试了 10 万次分配和 if-ing。事实证明,分配速度更快。(54毫秒用于IF-ing,44ms用于分配)

您所描述的称为"静默存储"优化。

优点:避免不必要的商店。

这可以减轻存储加载转发缓冲区的压力,转发缓冲区是现代无序 CPU 的一个组件,在硬件上非常昂贵,因此经常尺寸过小,因此是性能瓶颈。在英特尔 x86 CPU 上,有性能事件监控计数器 (EMON),可用于调查这是否是程序中的问题。

有趣的是,它还可以减少程序执行的加载次数。首先,软件:如果不消除存储,编译器可能无法证明不写入所占用的内存的不同变量,即所谓的地址和指针消歧问题,因此编译器可能会生成不必要的重新加载这种可能但实际上并不冲突的内存位置。消除商店,其中一些 loD 也可能被消除。其次,硬件:大多数现代 CPU 都有存储到负载依赖关系预测器:更少的存储提高准确性。如果预测了依赖关系,则负载实际上可能不是由硬件执行的,并且可能会转换为寄存器以寄存器移动。这是威斯康星大学最近对英特尔和苹果提起的专利诉讼的主题,赔偿额超过数亿美元。

但是消除不必要的存储的最重要原因是避免不必要地弄脏缓存。脏缓存行最终必须写入内存,即使没有变化。 浪费电力。在许多系统中,它最终将被写入闪存或SSD,浪费功率并消耗设备有限的写入周期。

这些考虑激发了在无声商店(如 http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.28.8947&rep=rep1&type=pdf)中进行学术研究。然而,快速的谷歌学术搜索显示这些论文主要是2000-2004年,我知道没有现代CPU实现真正的无声存储消除 - 实际上让硬件读取旧值。然而,我怀疑,这种缺乏静音存储的缺乏主要是因为CPU设计暂停了十多年,因为焦点从台式PC转向手机。现在手机几乎赶上了2000年代台式机CPU的复杂程度,它可能会再次出现。

缺点:消除软件中的静默存储需要更多的说明。更糟糕的是,它需要一个分支。如果分支不是很可预测,则由此产生的分支错误预测将消耗任何节省。某些机器具有允许您在没有分支的情况下消除此类存储的指令:例如英特尔的带有条件向量掩码的 LRBNI 矢量存储指令。我相信AVX有这些说明。如果您或您的编译器可以使用此类指令,那么成本只是旧值的负载和向量比较,如果旧值已经在寄存器中,则只是比较。

顺便说一句,您可以在不完全消除商店的情况下获得一些好处,而是将其重定向到安全地址。相反,如果

如果 a[i] != 0 则 a[i] := 0

ptr = a+I;如果 *ptr == 0,则 ptr.:= &safe; *ptr:=0

仍然在做商店,但没有弄脏这么多缓存行。如果经常伪造有条件的存储指令,我已经使用了这种方式。编译器不太可能进行这种优化。

因此,不幸的是,答案是"视情况而定"。 如果你使用的是矢量掩码机或GPU,并且静音存储非常普遍,例如,超过30%,值得考虑。如果在标量代码中,可能需要更多像 90% 的静音。

理想情况下,自己测量。尽管很难进行实际测量。

我将从优化的最佳情况开始:

字符 a[1024*1024

*1024];//零填充常量整数缓存行大小 = 64;for(char*p=a; p

这里消除了每个存储 - mAke 确保编译器仍然发出它们。良好的分支预测等

如果此限制情况没有任何好处,那么您的实际代码不太可能。

想想看,我在上个世纪运行了这样的基准。 静默存储代码的速度提高了 2 倍,因为完全内存绑定,并且静默存储不会在回写缓存上生成脏缓存行。因此,重新检查,然后尝试更实际的工作负载。

但首先,衡量你是否是记忆瓶颈。


顺便说一句:如果消除静默存储的硬件实现变得普遍,那么您将永远不想在软件中做到这一点。

但目前,我知道在商用 CPU 中没有消除静默存储的硬件实现。

随着 ECC 变得越来越普遍,静默存储消除几乎是免费的 - 因为在许多情况下,您无论如何都必须读取旧字节才能重新计算 ECC。

赋值会更好地为您服务,因为首先if语句是多余的,如果您省略它会更清晰,而且赋值应该更快,即使您不太确定它,您也可以创建一个简单的函数来测试它有和没有 if 语句。