【发布时间】:2018-12-28 18:18:09
【问题描述】:
我通过执行循环来对一些基本例程进行基准测试,例如:
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
【问题讨论】:
-
defined behavior 怎么可能涉及“更多工作”?
-
我不明白这个问题,但通常有很多方法可以得到结果。然后是 sqrt 等的 errno 问题......所以可能的问题很简单,是否需要像其他例程一样快速循环。
-
对于它的价值,使用 -ffast-math 生成的程序集对于
round和floor来说实际上是相同的。 -
好吧,
round将不得不分支,因为它可以向上或向下,而其他所有方向都只是一个方向。您使用了哪些优化标志?你是如何计时的? -
@NathanOliver 这与分支无关。有一系列 SSE 舍入指令可以在硬件中有效地进行舍入,但由于某种原因,它不用于
round,而是用于floor(除非打开 -ffast-math)。我也很好奇为什么会这样。可能只是实施质量问题。
标签: c++ rounding clang++ floor