C++ 关于回路中的值钳制的优化建议

C++ 关于回路中的值钳制的优化建议,c++,c++11,assembly,c++14,inline-assembly,C++,C++11,Assembly,C++14,Inline Assembly,我有一个紧密的循环,就像钱德勒·卡鲁斯在2017年CPP大会上展示的一样: 在本视频的25分钟内,有一个循环如下: for (int& i:v) i = i>255?255:i; 其中v是一个向量。这与我的程序中使用的代码完全相同,经过分析,证明需要花费大量的时间 在他的演示中,钱德勒修改了装配并加速了循环。我的问题是,在实际的生产代码中,推荐的优化方法是什么?在C++代码中使用内联汇编吗?还是像钱德勒那样,将C++代码编译成程序集,然后优化汇编程序? 假设采用x86体系

我有一个紧密的循环,就像钱德勒·卡鲁斯在2017年CPP大会上展示的一样: 在本视频的25分钟内,有一个循环如下:

for (int& i:v)
    i = i>255?255:i;
其中
v
是一个向量。这与我的程序中使用的代码完全相同,经过分析,证明需要花费大量的时间

在他的演示中,钱德勒修改了装配并加速了循环。我的问题是,在实际的生产代码中,推荐的优化方法是什么?在C++代码中使用内联汇编吗?还是像钱德勒那样,将C++代码编译成程序集,然后优化汇编程序? 假设采用x86体系结构,我们将非常欣赏优化上述for循环的示例

我的问题是,在实际的生产代码中,推荐的优化方法是什么?在C++代码中使用内联汇编吗?还是像钱德勒那样,将C++代码编译成程序集,然后优化汇编程序? 对于生产代码,您需要考虑软件可以在自动生成系统中编译和链接。 在这样的系统中,您希望如何将代码更改应用于汇编代码?您可以应用一个diff文件,但如果更改了优化(或其他)设置,如果切换到其他编译器或

现在剩下两个选项:在汇编文件(s)中写入整个函数,或者在C++代码里面有内联汇编代码——后者可能有将相关代码保存在同一个翻译单元中的优点。

尽管如此,我还是让编译器生成一次汇编代码——具有最高的优化级别。然后,这个代码可以作为一个(已经预先优化的)基,用于手工优化,然后将结果粘贴回内嵌程序集到C++源文件中,或者放入单独的汇编源文件中。 我的问题是,在实际的生产代码中,推荐的优化方法是什么?在C++代码中使用内联汇编吗?还是像钱德勒那样,将C++代码编译成程序集,然后优化汇编程序? 对于生产代码,您需要考虑软件可以在自动生成系统中编译和链接。 在这样的系统中,您希望如何将代码更改应用于汇编代码?您可以应用一个diff文件,但如果更改了优化(或其他)设置,如果切换到其他编译器或

现在剩下两个选项:在汇编文件(s)中写入整个函数,或者在C++代码里面有内联汇编代码——后者可能有将相关代码保存在同一个翻译单元中的优点。


尽管如此,我还是让编译器生成一次汇编代码——具有最高的优化级别。然后,此代码可以作为(已预优化)手动优化的基础,其中的结果然后被粘贴回C++源文件的内嵌程序集或放置到一个单独的汇编源文件中。

< P> < St>钱德勒修改了编译器的ASM输出,因为这是一个简单的方法来进行一个一次性的实验,以发现更改是否有用[<强>如果不做所有的事情,您通常希望将asm循环或函数作为项目源代码的一部分

编译器生成的asm通常是优化循环的良好起点,但实际上保持整个文件的原样并不是将循环的asm实现作为程序的一部分进行实际维护的好方法,甚至是不可行的方法。见@Aconcagua的答案

另外,它在C++编写的文件中有其他功能,并且可用于链接时间优化。


Re:实际夹紧:

请注意,Chandler只是在试验对非矢量化代码的更改,并禁用了展开+自动矢量化。在现实生活中,希望您可以将SSE4.1或AVX2作为目标,并让编译器使用带符号或无符号int钳制自动向量化到上限。(也可在其他元素大小中使用。或者不使用SSE4.1,仅使用SSE2,也许您可以使用2x
PACKSSDW
=>(无符号饱和),然后使用零解包,最多可返回4个dword元素向量。(如果您不能仅使用
uint8_t[]

顺便说一句,结果证明他犯了一个错误,他看到的效果并不是因为一个可预测的分支与cmov。这可能是一个代码对齐的事情,因为从
mov%ebx,(%rdi)
更改为
movl$255,(%rdi)
产生了不同

(众所周知,AMD CPU不像P6系列那样存在寄存器读取暂停,应该可以毫不费力地隐藏cmov将存储连接到负载的dep链,而不是通过分支预测+推测来破坏它。)



<>你很少希望使用手写循环。通常你可以通过修改C++源来手握和/或欺骗编译器使ASM更像你想要的。然后,将来的编译器可以自由地调整< <代码> > Max=某些未来的CPU /代码>。< /P> < P> <强>钱德勒修改编译器的ASM输出BECA。使用这是一种简单的方法来进行一次性实验,以确定更改是否有用,而无需做通常希望在项目源代码中包含asm循环或函数的所有工作

编译器生成的asm通常是优化循环的良好起点,但实际上保持整个文件的原样并不是将循环的asm实现作为程序的一部分进行实际维护的好方法,甚至是不可行的方法。请参阅@Aconcagua的答案

另外,它在C++编写的文件中有其他功能,并且可用于链接时间优化。


Re:实际夹紧:

请注意,钱德勒只是在试验对