gpt4 book ai didi

c++ - 这是矢量化的好做法吗?

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:10:37 25 4
gpt4 key购买 nike

我正在尝试提高 this 的性能通过向量化此函数来编写代码:

inline float calcHaarPattern( const int* origin, const SurfHF* f, int n )
{
double d = 0;
for( int k = 0; k < n; k++ )
d += (origin[f[k].p0] + origin[f[k].p3] - origin[f[k].p1] - origin[f[k].p2])*f[k].w;
return (float)d;
}

据我所知,您可以矢量化涉及恰好一个数学运算的循环。在上面的代码中,我们有 5 个数学运算,所以(使用 OMP):

#pragma omp simd
for( int k = 0; k < n; k++ )
d += (origin[f[k].p0] + origin[f[k].p3] - origin[f[k].p1] - origin[f[k].p2])*f[k].w;

这行不通。但是,我在想如果只用一个数学运算将上面的循环分成多个循环是矢量化的好做法吗?生成的代码将是:

double p0[n], p3[n], p1[n], p2[n];
#pragma omp simd
for( int k = 0; k < n; k++ )
p0[k] = origin[f[k].p0]*f[k].w;
#pragma omp simd
for( int k = 0; k < n; k++ )
p3[k] = origin[f[k].p3]*f[k].w;
#pragma omp simd
for( int k = 0; k < n; k++ )
p1[k] = origin[f[k].p1]*f[k].w;
#pragma omp simd
for( int k = 0; k < n; k++ )
p2[k] = origin[f[k].p2]*f[k].w;
#pragma omp simd
for( int k = 0; k < n; k++ )
d += p0[k];
#pragma omp simd
for( int k = 0; k < n; k++ )
d -= p1[k];
#pragma omp simd
for( int k = 0; k < n; k++ )
d -= p2[k];
#pragma omp simd
for( int k = 0; k < n; k++ )
d += p3[k];

这是一个好的解决方案,还是有更好的解决方案?现代编译器(比如 gcc)将自行进行这种(或更好的)优化(例如启用 -O3)(因此实际上没有性能提升) ?

最佳答案

这通常是糟糕的 HPC 编程实践,原因如下:

  1. 如今,您通常必须使代码尽可能计算密集。为此,您需要尽可能为循环设置更高的算术强度 (AI)。为简单起见,将 AI 视为 [计算量] 除以 [为了执行这些计算而移入/移出内存的字节数]。通过拆分循环,您可以使每个循环的 AI 在您的情况下低得多,因为您不再为不同的计算重复使用相同的字节。
  2. (Vector- 或 Thread-) -Parallel Reduction(在您的情况下为变量“d”)具有您不想乘以 8 或 10(即按数字)的成本/开销由您手工制作的循环)。
  3. 在许多情况下,当在同一个循环体中处理同一数据对象的多个数据字段而不是拆分循环的情况时,Intel/CGG 编译器矢量化引擎可以进行稍微更好的优化。

循环拆分的理论优势也很少,但它们不适用于您的情况,因此我提供它们以防万一。在以下情况下,循环拆分是合理的/有利可图的:

  • 在循环中存在多个循环依赖或减少相同的循环。
  • 以防循环拆分有助于摆脱一些乱序执行数据流依赖。
  • 以防您没有足够的 vector 寄存器来执行所有计算(对于复杂算法)。

Intel Advisor (您在上一个问题中提到过)有助于分析许多这些因素并衡量 AI。

这也是事实,好的编译器“不关心”每当您有一个这样的循环或循环拆分时,因为它们可以轻松地将一种情况转换为另一种情况,反之亦然。然而,这种转换在实际代码中的适用性非常有限,因为要做到这一点,您必须在编译时知道很多额外信息:指针或动态数组是否重叠,数据是否对齐等等等等。所以您不应该依赖编译器转换和特定的编译器次要版本,而是尽可能多地编写 HPC 就绪代码。

关于c++ - 这是矢量化的好做法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42175752/

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