针对跨模式访问的 SIMD 优化
SIMD optimisation for cross-pattern access
我正在尝试编写伊辛模型的蒙特卡罗模拟,我想知道是否可以使用 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
s 的平面std::vector
的方法。我看到可能存在一些问题:访问有很多三元逻辑(对于周期性边界条件),并且没有一个向量元素是相邻的。是为了对这个区块进行SIMD
优化,还是我应该继续挖掘?重新实现邻接矩阵和/或使用不同的容器(例如数组或不同类型的向量)是一种选择。
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
相关文章:
- 空基优化子对象的地址
- 关闭||运算符优化
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- 返回值优化:显式移动还是隐式
- 人脸跟踪arduino代码的优化
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 纯函数,为什么没有优化
- 为什么大多数 pair 实现默认不使用压缩(空基优化)?
- 如何以优化的方式同时迭代两个间距不相等的数组
- 小字符串优化(调试与发布模式)
- 浮点定向舍入和优化
- 在 C++ 中使用 SIMD 向量的矩阵乘法
- Visual Studio 调试优化如何工作?
- 为什么开关的优化方式与 c/c++ 中的链接不同?
- 针对跨模式访问的 SIMD 优化
- 从第二个导数计算的曲线的SIMD优化
- 优化的 SIMD 矢量库无法通过等效标量运算执行
- 如何优化 SIMD 转置功能 (8x4 => 4x8)?
- 块匹配优化使用x86/x64流SIMD扩展
- 如何优化If/then条件表达式的长序列- SIMD