首页 > 解决方案 > 比 LLVM 中的 floor/ceil/int 慢得多

问题描述

我通过执行循环来对一些基本例程进行基准测试,例如:

float *src, *dst;
for (int i=0; i<cnt; i++) dst[i] = round(src[i]);

全部带有 AVX2 目标,最新的 CLANG。有趣的是 floor(x)、ceil(x)、int(x)... 看起来都很快。但是 round(x) 似乎非常慢,并且在进行反汇编时,有一些奇怪的意大利面条代码,而不是较新的 SSE 或 AVX 版本。即使通过引入一些依赖性来阻止矢量化循环的能力,轮次也慢了 10 倍。对于 floor 等,生成的代码使用 vroundss,对于 round 有意大利面条代码......有什么想法吗?

编辑:我正在使用 -ffast-math, -mfpmath=sse, -fno-math-errno, -O3, -std=c++17, -march=core-avx2 -mavx2 -mfma

标签: c++roundingclang++floor

解决方案


问题是没有一个 SSE 舍入模式为 指定正确的舍入round

这些函数将 x 舍入为最接近的整数,但从零开始舍入一半的情况(无论当前舍入方向如何,请参阅 fenv(3)),而不是像 rint(3) 那样最接近的偶数。

如果您想要更快的代码,您可以尝试 testingrint而不是round,因为它指定了 SSE 支持的舍入模式。


推荐阅读