Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 用于AVX操作的双对齐与浮动对齐_C++_Memory Alignment_Avx - Fatal编程技术网

C++ 用于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

我想用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);

编辑:我发现了我的错误,这是以前函数的复制/粘贴错误,在该函数中表现出来。由于对其他人没有帮助(我假设),我结束了这个问题。

好吧,您的问题似乎源于不同的数据大小

  • 在第一个代码段中,您将
    float
    循环增加到
    SIZE/8
    =8192。在这里,我不确定为什么要将元素大小为4的
    FLOAT
    数组增加8。所以
    i<8192
  • 在第二个代码段中,将
    双循环增加到
    大小/4
    =16384。在这里,我不确定为什么要将元素大小为8的
    数组增加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 ...