【发布时间】:2017-11-11 03:28:09
【问题描述】:
我正在学习如何使用 C 语言使用 SIMD 指令,并且我想比较使用 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 上进行测试...
【问题讨论】:
-
所以,我的大部分问题都与使用 calloc 有关!我不确定来源,但我很确定我在某处看到操作系统可以用 calloc 做一些非常奇特的事情。如果我运行循环并将所有值分配给 0,则标准方法的时间差将回到 0.35 秒,而 SIMD 方法的时间差会回到 0.05 秒。我认为这代表了我的数组已初始化的真实世界用例(完全,即显式设置的每个值)。
-
更新: malloc 也会出现这种情况。那么这是操作系统的问题还是处理器的一些奇怪的缓存效果?
-
没有看到你是如何测试的,我只能猜测,但听起来你正在测试你的分配代码以及你试图加速的任何操作。也有可能即使您没有,您分配的内存也没有被触及,因此访问它会导致页面错误,因为它被交换或映射。最好包含您的实际测试代码以获得真正的答案。
-
我在网上发布了一个要点。我将内存分配增加得更高(1e9 个样本),并且保持相同的趋势。
-
如果 malloc 或 calloc 并且只读取它,则所有页面都可以写入时复制映射到相同的物理零页面,因此您可以获得 L1D 缓存命中。您的问题对您的访问模式不是很清楚。或者关于您正在测试的硬件。
标签: c performance simd