我强烈建议您看看OpenCL ,而不是为您的标量代码手动编写替代 SSE 实现。它是一个供应商中立的便携式跨平台系统,适用于计算密集型应用程序(并且高度符合流行语!)。您可以在为矢量化操作设计的 C99 子集中编写算法,这比手动编码 SSE 容易得多。最重要的是,OpenCL 将在运行时生成最佳实现,既可以在 GPU 上执行,也可以在CPU上执行。所以基本上你会得到为你编写的 SSE 代码。
在我的代码库中有几个地方,对于大型数据集,相同的操作会重复很多次。在某些情况下,处理这些需要相当长的时间。
您的应用程序听起来正是 OpenCL 旨在解决的问题。在 SSE 中编写替代函数当然会提高执行速度,但编写和调试工作量很大。
是否有一种独立于编译器和操作系统的方式编写代码以利用 SSE 指令?我喜欢包含 SSE 操作的 VC++ 内在函数,但我还没有找到任何交叉编译器解决方案。
是的。SSE 内在函数基本上已由 Intel 标准化,因此相同的函数在 Windows、Linux 和 Mac 之间的工作方式相同(特别是在 Visual C++ 和 GNU g++ 中)。
我仍然需要支持一些没有或有限 SSE 支持的 CPU(例如 Intel Celeron)。是否有某种方法可以避免必须制作不同版本的程序,例如拥有某种“运行时链接器”,该链接器根据进程启动时运行它的 CPU 链接基本或 SSE 优化代码?
您可以这样做(例如使用dlopen()
),但这是一个非常复杂的解决方案。更简单的是(在 C 中)定义函数接口并通过函数指针调用优化函数的适当版本,或者在 C++ 中使用不同的实现类,具体取决于检测到的 CPU。
对于 OpenCL,没有必要这样做,因为代码是在运行时为给定架构生成的。
其他 CPU 扩展怎么样,看看各种 Intel 和 AMD CPU 的指令集显示有几个?
在 SSE 指令集中,有许多不同的风格。当某些指令不存在时,在 SSE 的不同子集中编写相同的算法可能非常困难。我建议(至少在开始时)您选择支持的最低级别,例如 SSE2,然后回退到旧机器上的标量实现。
这也是单元/回归测试的理想情况,这对于确保您的不同实现产生相同结果非常重要。拥有输入数据和已知良好输出数据的测试套件,并通过两个版本的处理函数运行相同的数据。您可能需要进行精确测试才能通过(例如,结果与正确答案之间的差异 epsilon 如下所示1e6
)。这将极大地帮助调试,如果您在测试框架中构建高分辨率时序,您可以同时比较性能改进。