我想将两个(浮点/双)矢量与AVX运算符相乘。为了做到这一点,我需要对齐记忆。我的浮点值函数是:
#define SIZE 65536
float *g, *h, *j;
g = (float*)aligned_alloc(32, sizeof(float)*SIZE);
h = (float*)aligned_alloc(32, sizeof(float)*SIZE);
j = (float*)aligned_alloc(32, sizeof(float)*SIZE);
//Filling g and h with data
for(int i = 0; i < SIZE/8; i++)
{
__m256 a_a, b_a, c_a;
a_a = _mm256_load_ps(g+8*i);
b_a = _mm256_load_ps(h+8*i);
c_a = _mm256_mul_ps(a_a, b_a);
_mm256_store_ps (j+i*8, c_a);
}
free(g);
free(h);
free(j);
这样可行,但是当我尝试使用double值时,我会收到内存访问错误(例如内存未正确对齐):
double *g_d, *h_d, *i_d;
g_d = (double*)aligned_alloc(32, sizeof(double)*SIZE);
h_d = (double*)aligned_alloc(32, sizeof(double)*SIZE);
i_d = (double*)aligned_alloc(32, sizeof(double)*SIZE);
for(int i = 0; i < SIZE/4; i++)
{
__m256d a_a, b_a, c_a;
a_a = _mm256_load_pd(g_d+4*i);
b_a = _mm256_load_pd(h_d+4*i);
c_a = _mm256_mul_pd(a_a, b_a);
_mm256_store_pd (i_d+i*4, c_a);
}
free(g_d);
free(h_d);
free(i_d);
为什么对齐不适用于double
- 值?
在gdb中运行时,我得到了
Program received signal SIGSEGV, Segmentation fault.
0x0000000000401669 in _mm256_load_pd (__P=0x619f70) at /usr/lib/gcc/x86_64-linux-gnu/5/include/avxintrin.h:836
编辑:我发现了我的错误,它是来自前一个函数的复制/粘贴错误,表现在该函数中。由于对其他人没有帮助(正如我所假设的),我提出了这个问题。
答案 0 :(得分:0)
好吧,您的问题似乎源于不同的数据大小。
float
循环增加到SIZE/8
= 8192。在这里,我不确定为什么要增加元素大小为4的FLOAT
数组。所以i < 8192
double
循环增加到SIZE/4
= 16384。在这里,我不确定为什么要增加元素大小为8的DOUBLE
数组。所以i < 16384
--- **相反!** DOUBLE
数组的最后一个元素可能会超越你的内存边界!
在这两种情况下,您都可以使用i++
增加循环次数。案件如下:
首先:(FLOAT(4))j + i * 8(0&lt; i&lt; 8192)=&gt;
0 4 8 12 16 20 24 28
v1 . v2 . v3 . v4 .
第二:( DOUBLE(8))j + i * 4(0&lt; i&lt; 16384)=&gt; V1 / V2 / V3 / V4
0 4 8 12 16 20 24 28 32
v1(h) v1(l) v2(l) v3(l) v4(l) v5(l) v6(l) v7(l)
v1(h) v2(h) v3(h) v4(h) v5(h) v6(h) v7(h) v8(h) v8(h)
--------------------------------------------------------------
some thing ... some thing ... some thing .. some thing ...
在第二个片段中,您将64位Double的高部分(32位)和低部分(32位)混合为仅增加4(sizeof FLOAT)而不是8(sizeof DOUBLE)。
另一个问题是_mm256_store_pd
要求......
当源或目标操作数是内存操作数时,操作数必须在32字节边界上对齐,否则将生成一般保护异常(#GP)。
for(int i = 0; i < SIZE/4; i++)
无法满足此要求。
我想知道您的FLOAT
版本似乎有效,因为_mm256_store_ps
要求... {/ p>
当源或目标操作数是内存操作数时,操作数必须在16字节边界上对齐,否则将生成一般保护异常(#GP)。
但你只有8个字节的对齐...
但是,您需要修复&#39;比例尺。您的i
变量可以使其发挥作用。