gpt4 book ai didi

c++ - 内部 if 语句杀死矢量化

转载 作者:搜寻专家 更新时间:2023-10-31 01:13:01 25 4
gpt4 key购买 nike

我有以下 for 循环。当我打开类型数组时,代码不会矢量化。当我将类型固定为“1”时,gcc 会执行 primitize vectorization vectorizes。有没有人有任何建议来触发某种矢量化?

#define type(M,N) type[(M)*sizeX + (N)]
for (int i = 0; i < sizeY - 1; i++)
{
for (int j = 0; j < sizeX - 1; j++)
{
const int id = type(i, j);
//const int id = 1; //vectorizes
const float A = this->A[id];
const float B = this->B[id];
a(i, j) = A * a(i, j) + B * (b(i, j) - b(i + 1, j))*(p[i]);
}
}

gcc 4.7.1 的近似错误

45: not vectorized: not suitable for gather A_26 = *D.14145_25;

编辑 1

所有数组都存储为指针,并使用 restrict 关键字定义为某个类的成员。

编辑 2

如果“type”很小,我能做些什么吗?

编辑 3

小意味着 8。

最佳答案

区别在于内存访问。

id = 1时,后面的数组加载变成单元素 vector 广播。

 const float A = this->A[id];
const float B = this->B[id];

但是当 id = type[(i)*sizeX + (k)] 时,内存访问是跨步的(不连续的)。

SSE 和 AVX 中的 vector 加载和存储只能在:

  1. 连续的内存块。
  2. 或者从广播到整个 vector 的单个元素。

它们无法处理从内存的不同部分加载每个 vector 元素的跨步内存访问。

AVX2 将支持此类“聚集/分散”指令。


解决编辑问题:

如果 type(i, j) 中的 i 不是零,内存访问仍然是跨步的。所以很难向量化。 (我说“困难”而不是“不可能”,因为编译时确定的步幅非常小是可能的——尽管效率会降低。)

这里的核心问题是您要迭代矩阵的行。如果没有收集/分散支持,这不仅不可矢量化,而且对缓存也不利。

我不确定您要完成什么任务,但您可能需要考虑不同的数据布局以获得最佳性能。

关于c++ - 内部 if 语句杀死矢量化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13136598/

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