为什么棕褐色在环境中比孤立时慢?

nos*_*ins 9 c performance x86 clang avx

运行附加的示例程序时,该函数tan在上下文中的速度似乎是孤立时的两倍。这是我机器上的输出:

justtan(): ~16.062430 ns/iter
notan():   ~30.852820 ns/iter
withtan(): ~60.703100 ns/iter
empty():   ~0.355270 ns/iter
Run Code Online (Sandbox Code Playgroud)

鉴于它是和的组合,我预计withtan()约为 45ns 或更低。justtannotan

我正在使用 Intel i7-4980HQ CPU 运行 macOS 11.5.2。我的cc --versionApple clang version 13.0.0 (clang-1300.0.29.3)。我已经检查过,以确保除了对 的调用之外,withtan和 的notan反汇编是相同的tan,并且 clang 使用 VEX 指令对循环进行自动矢量化。我还通过调试器检查了运行时调用的版本tan是否也利用 VEX 指令来避免 SSE-AVX2 转换损失。

我在Linux VM中编译并运行了该程序,并得到了类似的结果(在调试器中,tan也使用AVX/VEX)。此外,我通过cachegrind运行它,发现任何函数基本上都没有L1缓存未命中(0.00%),但是当通过cachegrind运行时,所有时间都正确地加起来。

这就是我运行可执行文件的方式:

cc -Wall -O3 -mavx2 -o main main.c && ./main

这是main.c

justtan(): ~16.062430 ns/iter
notan():   ~30.852820 ns/iter
withtan(): ~60.703100 ns/iter
empty():   ~0.355270 ns/iter
Run Code Online (Sandbox Code Playgroud)

为什么tan在上下文中比在孤立时慢?

Aki*_*nen 2

顺便说一句,同样的行为也出现在 Macbook M1 上,数字分别是 4 vs 14 vs 28 vs 0.3。

使用 withtan =tan(black_box(96)) + a + b + c + d为 20 ns/iter,这对我来说暗示tan(a+b+c+d)创建 OoO 单元无法打破的依赖关系,其中计算所有 sum_a、sum_b、sum_c、sum_d、tan(96) 都是独立任务,可以无序运行。

问题之一还必须是tan足够长,以便 OoO 单元无法窥视下一个独立迭代。

  • 我认为15/7/30这个数字仍然符合`a+a+a+...`可以OoO执行独立循环的理论,`a+b+c+d...`也可以OoO执行,所以是“tan+tan+tan...”吗?但`tan(whatever)`不会,因为`tan`太长了。当然,可以通过使用更短的函数来测试该假设,例如使用 sqrt() 代替(使用 -ffast-math)——时间确实加起来,表明“a+b+...”的下一次迭代可以开始而 `sqrt` 仍在执行。 (2认同)