我在Visual Studio 2008中工作,在项目设置中,我看到“激活扩展指令集”的选项,我可以将其设置为None,SSE或SSE2
那么编译器会尝试将指令一起批处理以便使用SIMD指令吗?
是否有任何规则可以遵循如何优化代码,以便编译器可以使用这些扩展来制作高效的汇编程序?
例如,目前我正在研究光线跟踪器。着色器接受一些输入并从输入计算输出颜色,如下所示:
PixelData data = RayTracer::gatherPixelData(pixel.x, pixel.y);
Color col = shadePixel(data);
例如,编写着色器代码是否有利于在一次指令调用中遮蔽4个不同的像素?像这样的东西:
PixelData data1 = RayTracer::gatherPixelData(pixel1.x, pixel1.y);
...
shadePixels(data1, data2, data3, data4, &col1out, &col2out, &col3out, &col4out);
一次处理多个数据单元。这有利于使编译器使用SSE指令吗?
谢谢!
答案 0 :(得分:5)
我在Visual Studio 2008中工作,在项目设置中,我看到“激活扩展指令集”的选项,我可以将其设置为None,SSE或SSE2
那么编译器会尝试将指令一起批处理以便使用SIMD指令吗?
不,编译器不会单独使用向量指令。它将使用标量SSE指令而不是x87指令。
您描述的内容称为“自动矢量化”。 Microsoft编译器不执行此操作,Intel compilers执行此操作。
在Microsoft编译器上,您可以使用intrinsics执行手动SSE优化。
答案 1 :(得分:3)
三个观察结果。
最佳加速并非来自优化,而是来自良好算法。因此,请确保您首先获得该部分。通常这意味着只为您的特定域使用正确的库。
一旦您的算法正确,就可以测量了。工作中通常有80/20规则。 20%的代码将占用80%的执行时间。但是为了找到那个部分你需要一个好的剖析器。 Intel VTune可以为您提供每个功能的抽样配置文件以及精确定位性能杀手的精彩报告。如果您有AMD CPU,则另一个免费替代方案是AMD CodeAnalyst。
编译器自动向量化功能不是灵丹妙药。虽然它会非常努力(尤其是Intel C++),但您通常需要通过以矢量形式重写算法来帮助它。通过手工制作瓶颈代码的一小部分来使用SIMD指令,您通常可以获得更好的结果。您可以使用内在函数或使用内联汇编在C代码(请参阅上面的VJo链接)中执行此操作。
当然,第2和第3部分形成了一个迭代过程。如果您对此非常认真,那么英特尔人员可以提供一些关于这一主题的好书,例如The Software Optimization Cookbook和处理器参考手册。
答案 2 :(得分:0)
编译器并非都强大,而且有一些限制。如果可以(如果传递了正确的标志),它将使用SSE指令。查看它所做的唯一方法是检查编译器生成的汇编代码。
另一种选择是使用C SSE / SSE2指令。对于Windows,你可以在这里找到它们:
http://msdn.microsoft.com/en-us/library/y0dh78ez%28VS.80%29.aspx