9

我在 Visual Studio 2008 中工作,在项目设置中我看到“激活扩展指令集”选项,我可以将其设置为无、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 指令吗?

谢谢!

4

3 回答 3

5

我在 Visual Studio 2008 中工作,在项目设置中我看到“激活扩展指令集”选项,我可以将其设置为无、SSE 或 SSE2

那么编译器会尝试将指令一起批处理以利用 SIMD 指令吗?

不,编译器不会自己使用向量指令。它将使用标量 SSE 指令而不是 x87 指令。

您所描述的称为“自动矢量化”。微软编译器不这样做,英特尔编译器这样做。

在 Microsoft 编译器上,您可以使用内在函数来执行手动 SSE 优化。

于 2010-10-26T18:40:28.063 回答
3

三个观察。

  1. 最好的加速不是来自优化,而是来自好的算法。因此,请确保您首先正确处理该部分。这通常意味着只为您的特定域使用正确的库。

  2. 一旦你的算法正确,就该Measure了。工作中通常有一个 80/20 规则。20% 的代码将占用 80% 的执行时间。但是为了找到那个部分,你需要一个好的分析器。英特尔 VTune可以为您提供每个函数的采样配置文件和精确的性能杀手报告。如果你有 AMD CPU,另一个免费的选择是AMD CodeAnalyst 。

  3. 编译器自动向量化功能不是灵丹妙药。尽管它会非常努力(尤其是Intel C++),但您通常需要通过以向量形式重写算法来帮助它。通过手工制作一小部分瓶颈代码以使用 SIMD 指令,您通常可以获得更好的结果。您可以使用内部函数在 C 代码中执行此操作(请参阅上面的 VJo 链接)或使用内联汇编。

当然,第 2 部分和第 3 部分形成了一个迭代过程。如果您对此非常认真,那么英特尔人员会提供一些关于该主题的好书,例如软件优化手册和处理器参考手册。

于 2010-10-26T20:59:14.343 回答
0

编译器不是很强大,它有一些限制。如果可以(并且如果将正确的标志传递给它),它将使用 SSE 指令。查看它所做的唯一方法是检查编译器生成的汇编代码。

另一种选择是使用 C SSE/SSE2 指令。对于 Windows,您可以在此处找到它们:

http://msdn.microsoft.com/en-us/library/y0dh78ez%28VS.80%29.aspx

于 2010-10-26T18:36:39.343 回答