什么是相对于标准代码测试simd加速的正确方法

时间:2017-11-11 03:28:09

标签: c performance simd

我正在学习如何使用C语言使用SIMD指令,我希望将使用SIMD的代码与代码进行比较。有没有人有一个测试模板可以准确识别SIMD代码与标准代码的预期加速比?

具体而言,我已经注意到具体配置的以下近似性能时间:

SIMD first, single run:
SIMD: 0.15 s
standard: 0.35 s

SIMD first, standard second, repeated 10x:
SIMD: 0.15 s - first run, 0.05 s on subsequent runs
standard: 0.35 s - first run, 0.34 on subsequent runs

standard first, SIMD second, repeated 10x:
standard: 0.45 s - first run, 0.35 s on subsequent runs
SIMD: 0.05 s - first run, 0.05 s on subsequent runs

代码示例正在运行类型为uint16_t的1e8值的数据集。数据分配和初始化在循环之外。如果我在重复循环内分配数据,则循环都具有相同的时序。如果我在SIMD和标准部分之前执行此操作,而不是在先到先得之前执行此操作,我会获得更大的时间:

standard: 0.45 s
SIMD: 0.15 s

那么为什么数据分配会造成这样的时差呢?什么是真正的加速?

代码链接: https://gist.github.com/JimHokanson/55ce2e5cac75d7df6dc24dadf383e68f

我正在使用m3处理器测试2016年初的Macbook ......

1 个答案:

答案 0 :(得分:0)

所以看起来这个问题可能只是未能按预期实际初始化内存。我原以为它可能是SIMD测试的特定内容,而不仅仅是C。

正确的内存初始化方法如下所示:

data = malloc(1e8);
//- Do a loop to initialize data (previously memset to 0 but it was suggested that this may be optimized away)
//- Do SIMD comparison vs standard approach - loop and average results

优化设置:此外,请记住在尝试与std lib汇编代码竞争时启用优化!看到: why is strchr twice as fast as my simd code 基本要点是我将SIMD与标准库代码进行了比较,并进行了非常优化的组装。没有优化,SIMD代码太慢,但在优化后结果更合理。

过度优化:有时编译器会在一种情况下优化代码而不在另一种情况下优化代码。例如,我有以下代码:

for (size_t n2 = 0; n2 < n_loops_inner; n2++){
   str2 = memchr(str,'b',N);
   char_index2 = str2 - str;
}

但是这段代码执行得太快了。我在循环中搜索之前添加了以下行。

  str[(size_t)char_position] = 'b';

此外,我还将char_index2标记为volatile。这些变化共同提供了更合理的执行时间。 (即比没有这些变化慢1000倍)