C++ 用于AVX操作的双对齐与浮动对齐
我想用AVX运算符乘以两个(浮点/双精度)向量。为了做到这一点,我需要对齐内存。我的浮点值函数是:C++ 用于AVX操作的双对齐与浮动对齐,c++,memory-alignment,avx,C++,Memory Alignment,Avx,我想用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
#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);
编辑:我发现了我的错误,这是以前函数的复制/粘贴错误,在该函数中表现出来。由于对其他人没有帮助(我假设),我结束了这个问题。好吧,您的问题似乎源于不同的数据大小
- 在第一个代码段中,您将
循环增加到float
=8192。在这里,我不确定为什么要将元素大小为4的SIZE/8
数组增加8。所以FLOAT
i<8192
- 在第二个代码段中,将
双循环增加到
=16384。在这里,我不确定为什么要将元素大小为8的大小/4
数组增加4倍。因此,
-**恰恰相反**李>i<16384
DOUBLE
数组的最后一个元素可能会超出内存边界
在这两种情况下,都使用i++
增加循环。因此,案件的处理如下:
第一:(FLOAT(4))j+i*8(0
第二:(双(8))j+i*4(0v1/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 ...
在第二个代码段中,您通过只增加4(sizeof FLOAT)而不是8(sizeof Double)来混合64位Double的高部分(32位)和低部分(32位)
另一个问题是这需要
当源操作数或目标操作数是内存操作数时,操作数必须在32字节边界上对齐,否则将生成一般保护异常(#GP)
(inti=0;ifor
不满足该要求
我想知道你的FLOAT
版本是否有效,因为需要
当源操作数或目标操作数是内存操作数时,操作数必须在16字节边界上对齐,否则将生成一般保护异常(#GP)
但是您只有8个字节的对齐方式
但是,您需要修正
i
变量的“比例”才能使其起作用。这些标识符名称非常有用。a,b,d到底是什么?始终从文本编辑器复制/粘贴代码。从一个有这个问题的测试程序中,永远不要编造任何东西。修复了变量,但以后会添加一个简短的测试程序。适用于我(tm)。你用过调试器吗?它到底在哪一行上失败,它读取(或写入)的地址值是多少。确切的失败代码是什么。@MikeVine:我添加了调试器输出。@arc\u Lube:如果得到正确的结果,您真正的问题/问题可能是什么?我(简单地)分析了你的代码中潜在的弱点/错误。我不知道为什么你的测试代码会返回正确的值,我只是强调了问题的潜在根源。@arc_Luse:你的问题很奇怪:你说你的代码不工作是因为一个-我引用-内存访问错误(比如内存没有正确对齐)
。我试着去近似那个问题,你的答案是什么?换言之:如果你认为你的代码一切正常,为什么你要问一个问题?请注意float*x;浮动*y=x+k代码>按k x sizeof(float)
和类似的double
,我认为您对arc代码的分析是错误的。@zx485:我认为您可能会在这里混淆-4和8的因子是每个向量的元素数,不是以字节为单位的元素大小-我认为循环增量在OP的代码中实际上是正确的。@zx485:是的,这有点令人困惑,特别是OP使用了硬编码的文字而不是有意义的常量,但对于SIMD循环,增量将是每个向量的元素数,例如,如果数组中有SIZE
float
s,并且使用的AVX向量每个向量有8个float
s,则循环增量将为SIZE/8
。
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 4 8 12 16 20 24 28
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 ...