【问题标题】:c++ how to write code the compiler can easily optimize for SIMD?c++如何编写代码编译器可以轻松优化SIMD?
【发布时间】:2011-04-30 21:56:33
【问题描述】:

我在 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 指令吗?

谢谢!

【问题讨论】:

    标签: c++ compiler-construction simd


    【解决方案1】:

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

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

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

    您所描述的称为“自动矢量化”。 Microsoft 编译器不这样做,Intel compilers 这样做。

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

    【讨论】:

    【解决方案2】:

    三个观察。

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

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

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

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

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-14
        • 2013-09-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-31
        相关资源
        最近更新 更多