使用 AVX 功能时崩溃
Posted
技术标签:
【中文标题】使用 AVX 功能时崩溃【英文标题】:crashing when I using AVX function 【发布时间】: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。
我该怎么办?
【问题讨论】:
请修正您的格式,并指出故障发生在哪一行。 顺便说一句,值得一读the question on why not to cast the return value ofmalloc()
and family in C。
你应该调试j
和i
的值会出现这个错误,检查是否有超出范围的索引并计算出公式。提示:for (i = 0; i + 3 < m; i++)
如果您希望它真正快速运行,您将需要使用多个累加器来隐藏 FP add 的延迟。在 Skylake 上,vaddpd
有 4 个周期延迟,但每个周期有 2 个吞吐量(与 256 位负载相同),因此您需要同时保持 8 个向量加法在运行中,以成为 ALU / L1d 缓存吞吐量的瓶颈。除非您使用 -ffast-math
,否则编译器无法为您展开具有多个累加器的 FP 缩减。
m=(int)pow(2,8);
=> 1 << 8
【参考方案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 寄存器。以上是关于使用 AVX 功能时崩溃的主要内容,如果未能解决你的问题,请参考以下文章