【问题标题】:crashing when I using AVX function使用 AVX 功能时崩溃
【发布时间】:2018-05-03 08:00:46
【问题描述】:
#include "stdio.h"
#include "math.h"
#include "stdlib.h"
#include "x86intrin.h"

void dd_m(double *clo, int m) 
{
int j;
__m256d *vclo = (__m256d *)clo;
__m256d al=_mm256_set_pd(0,0,0,0);
__m256d clo_n=_mm256_set_pd(0,0,0,0);
int i;
for (j = 0; j < m; j++) {
    for (i = 0; i < m; i++) {
        al = _mm256_add_pd(vclo[m/4*j+i] , clo_n);
    }
}
}
int main(int argc, const char * argv[]){

int m;
double* zlo;
int i;


m=(int)pow(2,8);

zlo=(double *)_mm_malloc(sizeof(double) * m*m,32);
for (i=0;i<m*m;i++) {
    zlo[i]=0.0;
}
dd_m(zlo, m);

_mm_free(zlo);

return 0;
}

这是我的代码。 它会产生错误

“线程 1:EXC_BAD_ACCESS(代码=1,地址=0x102900000)”

在 for 循环内。

我使用最新的 xcode 和 clang。

我该怎么办?

【问题讨论】:

  • 请修正您的格式,并指出故障发生在哪一行。
  • 你应该调试ji的值会出现这个错误,检查是否有超出范围的索引并计算出公式。提示:for (i = 0; i + 3 &lt; m; i++)
  • 如果您希望它真正快速运行,您将需要使用多个累加器来隐藏 FP add 的延迟。在 Skylake 上,vaddpd 有 4 个周期延迟,但每个周期有 2 个吞吐量(与 256 位负载相同),因此您需要同时保持 8 个向量加法在运行中,以成为 ALU / L1d 缓存吞吐量的瓶颈。除非您使用 -ffast-math,否则编译器无法为您展开具有多个累加器的 FP 缩减。
  • m=(int)pow(2,8); => 1 &lt;&lt; 8

标签: c clang simd avx


【解决方案1】:

通过将clo 转换为vclo 指向256 位向量,您的行长度除以四,您在索引计算中更改了它,但在i 的内部循环中没有更改。

for (j = 0; j < m; j++) {
    for (i = 0; i < m/4; i++) { // in vclo, the rows are only m/4 long
        al = _mm256_add_pd(vclo[m/4*j+i] , clo_n);
    }
}

【讨论】:

  • 谢谢。但是,似乎只有 2 个 for 循环有效。如果有另一个循环我该怎么办...像那样... for (j = 0; j
  • 画出你的矩阵图,可视化循环嵌套中数据元素的访问方式,以真正理解代码。矩阵的行被分成 4 个双精度数的 SIMD 寄存器。遍历行的每个索引(即在 [...*...+...] 访问中的 + 右侧)只能从 0 变为 (row-length/4 - 1)。如果您遍历具有相同索引的列,即 k,它需要从 0 到 (column-height - 1) 的不同范围。您可能希望使用 clo 并通过强制转换构建一个包含 4 个行元素的 SIMD 寄存器,并通过收集构建一个包含 4 个列元素的 SIMD 寄存器。
猜你喜欢
  • 1970-01-01
  • 2013-02-10
  • 2021-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-25
  • 1970-01-01
相关资源
最近更新 更多