gpt4 book ai didi

c - 运行时不可整除循环大小对 openMP SIMD 的影响

转载 作者:行者123 更新时间:2023-11-30 16:21:26 25 4
gpt4 key购买 nike

在阅读了几篇不同的文章但没有找到答案后,我将介绍问题,然后提出问题。

我有一段代码可以简化为一系列循环,如下所示。

#pragma omp parallel for simd
for(int i = 0; i < a*b*c; i++)
{
array1[i] += array2[i] * array3[i];
}

现在,我遇到的大多数 SIMD 使用示例都在编译时固定了 a、b 和 c,以便进行优化。但是,我的代码要求 a b 和 c 的值在运行时确定。

假设对于我使用的计算机来说,寄存器可以容纳 4 个值,并且 abc 的值是 127。我对此的编译时间的理解是编译器将对所有可被 4 整除的所有内容进行矢量化,然后序列化其余部分(如果我错了,请更正)。然而,这是编译器完全了解问题的时候。如果我现在允许运行时选择 a、b 和 c 并得出值 127,矢量化将如何进行?天真地,我会假设幕后的代码足够智能,可以理解可能发生的情况,同时具有串行和 vector 代码,并调用最合适的。然而,由于这是一个假设,我希望有对此主题更有了解的人进一步启发我,因为我不希望由于误解而导致意外溢出或不处理数据。

如果这很重要,我将 OpenMP 4.0 与 C gcc 编译器一起使用,尽管我希望这不会改变您的答案,因为我将始终尝试使用最新的 OpenMP 版本,不幸的是可能需要定期更改编译器。

最佳答案

通常,编译器将展开超出 simd 长度。为了获得最佳结果,特别是对于 gcc,您可以指定此展开因子,例如--param max-unroll-times=2 (如果您不期望更长的循环)。如果 simd 长度为 4,循环将一次消耗 8 次迭代,留下余数。 gcc 将构建一个余数循环,有点像 Duff 的设备,可能有 15 次迭代,并且会计算在运行时跳转到哪里。英特尔编译器以不同的方式处理向量化余数循环。假设您有 2 个 simd 宽度可用,则余数循环将使用较短的宽度而不展开,以便串行部分尽可能短。当针对未对齐数据的一般情况进行编译时,两端都有一个余数循环,开头的循环仅限于存储值对齐所需的长度。结合 omp parallel simd 后,情况变得更加复杂;通常,循环 block 的大小必须有所不同,并且有人可能会争辩说,内部 block 可能被设置为对齐,而末端 block 较小(通常不这样做)。

关于c - 运行时不可整除循环大小对 openMP SIMD 的影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54865620/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com