gpt4 book ai didi

c++ - 针对交叉模式访问的 SIMD 优化

转载 作者:行者123 更新时间:2023-11-27 23:46:51 25 4
gpt4 key购买 nike

我正在尝试编写 Ising 模型的蒙特卡洛模拟,我想知道是否可以使用 SIMD 优化来以交叉模式访问数据。

我基本上想知道是否有任何方法可以加快此功能。

//up/down/left/right stencil accumulation
float lattice::compute_point_energy(int row, int col) {
int accumulator=0;
accumulator+= get(row? row-1: size_-1, col);
accumulator+= get((row+1)%size_, col);
accumulator+= get(row, col? col-1: size_-1);
accumulator+= get(row, (col+1)%size_) ;
return -get(row, col) * (accumulator * J_ + H_);
}

get(i, j) 是一种访问 short 的平面 std::vector 的方法。我看到可能存在一些问题:访问有很多三元逻辑正在进行(对于周期性边界条件),并且没有一个 vector 元素是相邻的。是为这个 block 做 SIMD 优化,还是我应该继续挖掘?重新实现邻接矩阵和/或使用不同的容器(例如数组或不同类型的 vector )是一种选择。

最佳答案

SIMD 是您最不想尝试使用此功能的东西。

认为您正在尝试使用上/下/左/右 4 模板进行计算。如果是这样,您的代码应该有注释说明这一点。

由于在三元运算符处可能发生分支并且模数相对较慢,因此您在此函数中损失了很多速度。

您最好在您操作的二维空间周围设置一圈单元格,这些单元格的值设置为适合处理边缘效应。这使您可以消除对边缘效应的检查。

为了访问您的模板,我发现使用类似以下内容通常很有效:

const int width  = 10;
const int height = 10;
const int offset[4] = {-1,1,-width,width};
double accumulator=0;
for(int i=0;i<4;i++)
accumulator += get(current_loc+offset[i]);

请注意,迷你阵列已预先计算到您域中相邻单元格的偏移量。一个好的编译器可能会展开上述循环。

一旦完成所有这些,适当的优化标志选择可能会导致自动矢量化。

事实上,您代码中的分支和模组可能会阻止自动矢量化。您可以通过启用适当的标志来检查这一点。对于英特尔编译器集合 (icc),您需要:

-qopt-report=5 -qopt-report-phase:vec

对于 GCC,您需要(如果我没记错的话):

-fopt-info-vec -fopt-info-missed

关于c++ - 针对交叉模式访问的 SIMD 优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49837898/

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