比LLVM中的floor / ceil / int慢得多

时间:2018-12-28 18:18:10

标签: c++ rounding clang++ floor

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

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倍。对于地板等,生成的代码使用vroundss,对于圆形,有意大利面条代码...有什么想法吗?

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

2 个答案:

答案 0 :(得分:3)

问题在于,没有任何SSE舍入模式为round指定正确的舍入:

  

这些函数将x舍入到最接近的整数,但是将中途情况舍入为零          (无论当前的取整方向如何,请参见fenv(3)),而不是取整          甚至像rint(3)这样的整数。

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

答案 1 :(得分:1)

要注意的一件事是,像floor(x + 0.5)这样的表达式虽然不具有与round(x)相同的语义,但在几乎所有用例中都是有效的替代品,我怀疑它是否接近比floor(x)慢10倍。