【发布时间】:2017-09-08 15:24:17
【问题描述】:
考虑一个由double 数字组成的排序(升序)数组。为了数值稳定性,应该对数组求和,就像从头到尾迭代一样,将总和累加到某个变量中。
如何使用 AVX2 有效地对其进行矢量化?
我已经研究过这个方法 Fastest way to do horizontal vector sum with AVX instructions ,但是将它扩展到一个数组似乎很棘手(可能需要一些分治方法),同时通过确保之前对小数字求和来保持浮点精度将它们添加到更大的数字中。
澄清 1:我认为应该可以,例如将前 4 项相加,然后将它们添加到接下来 4 项的总和中,等等。我愿意用一些稳定性来换取性能。但我更喜欢一种不会完全破坏稳定性的方法。
说明 2:内存不应成为瓶颈,因为数组位于 L3 缓存中(但不在 L1/L2 缓存中,因为数组的各个部分是从不同的线程填充的)。我不想诉诸 Kahan 求和,因为我认为真正重要的是操作的数量,而 Kahan 求和会增加大约 4 倍。
【问题讨论】:
-
升序求和不会杀死所有并行化空间吗?由于 FP 算术不是关联的,并且您明确谈论数字稳定性,我相信您需要从第一项到最后一项的序列和。顺便说一句,不是我的 DV。
-
@MargaretBloom,我已经更新了问题并对此进行了澄清。
-
嗯,如果您愿意牺牲一些稳定性,那么简单的并行求和就可以了,不是吗?您将 d[0]+d[4]+d[8]+..、d[1]+d[5]+d[9]+...等相加。
-
@SergeRogatch:假设你有很多数字(或者没有必要使用 SIMD)。在这种情况下,添加的数字不应太远。我认为您实际上应该检查一下我的推荐结果,看看您损失了多少精度。
-
@SergeRogatch:我明白了。我以为你的数字比几百多得多。但在这种情况下,您可以将最后 50-60 个数字相加,结果将是相同的。
标签: c++ algorithm floating-point vectorization x86-64