【发布时间】:2013-12-28 19:09:08
【问题描述】:
我正在转换 SSE2 正弦和余弦函数(来自 Julien Pommier 的 sse_mathfun.h;基于 CEPHES sinf 函数)以使用 AVX 以接受 8 个浮点向量或 4 个双精度。
因此,Julien 的函数 sin_ps 变为 sin_ps8(8 个浮点数)和 sin_pd4 4 个双精度数。 (这里的“高级”编辑器无法接受我的代码,请访问http://arstechnica.com/civis/viewtopic.php?f=20&t=1227375查看。)
在运行 2011 Core2 i7 @ 2.7Ghz 的 Mac OS X 10.6.8 下使用 clang 3.3 进行测试,基准测试结果如下所示:
-
sinf .. -> 2770 万次向量评估/秒超过 5.56e+07 iters(标准,标量 sinf() 函数)
sin_ps .. -> 4100 万次矢量评估/秒以上 8.22e+07 次
sin_pd4 .. -> 4020 万次矢量评估/秒以上 8.06e+07 次
sin_ps8 .. -> 250 万次矢量评估/秒以上 5.1e+06 次
sin_ps8 的成本非常可怕,似乎是因为使用了 _mm256_castsi256_ps 。实际上,注释掉“poly_mask = _mm256_castsi256_ps(emmm2);”这一行导致更正常的性能。 sin_pd4 使用 _mm_castsi128_pd,但在 sin_ps8 中咬我的似乎不是(只是)SSE 和 AVX 指令的混合:当我通过 2 次调用 _mm_castsi128_ps 来模拟 _mm256_castsi256_ps 调用时,性能并没有提高。 emm2 和 emm0 是指向 emmm2 和 emmm0 的指针,它们都是 v8si 实例,因此(先验)正确对齐到 32 位边界。
有关可编译代码,请参阅sse_mathfun.h 和sse_mathfun_test.c。
有没有一种(简单的)方法可以避免我看到的惩罚?
【问题讨论】:
-
非常抱歉缺少代码:预览看起来不错,但我的文字被拒绝发布...
-
Agner Fog 的 optimization tables 表明,无论参数大小如何,
ANDPS和VANDPS在 Ivy Bridge 和 Haswell 上都有 1 个周期的延迟。此外,_mm256_castsi256_ps实际上并不发出任何指令——它是真正的类型转换,纯粹在编译器中。您的问题可能出在其他地方。 -
我想提出几点。首先,如果您可以发布 Julien 和您的所有函数的汇编代码,我们会很高兴。在 Mac OS X 10.6.8 上,您可以使用
otool -tV -p <name of function prefixed with underscore>执行此操作。其次,由于您使用的是内在函数,我希望编译器会选择不会导致 SSE-AVX 转换惩罚的 VEX 前缀指令编码。我怀疑您的问题是由于 SSE-AVX 转换造成的。 -
第三,您在这里使用了一些 256 位整数数学。根据您的 CPU 的发布日期以及它具有 AVX 的事实,它是 Intel Sandy Bridge。 Sandy Bridge 和 Ivy Bridge 只支持 AVX 指令集,不像 Haswell 也支持 AVX2。 AVX 指令集仅包含完整的 256 位宽度的 浮点 操作,而整数指令仍然是 128 位宽度。 AVX2 是也有全角整数运算的指令集。
-
我没有看到他在任何地方使用 256 位整数数学