相关疑难解决方法(0)

使用AVX/AVX2内在函数对齐和未对齐的内存访问

根据英特尔软件开发人员手册(第14.9节),AVX放宽了内存访问的对齐要求.如果数据直接加载到处理指令中,例如

vaddps ymm0,ymm0,YMMWORD PTR [rax]
Run Code Online (Sandbox Code Playgroud)

加载地址不必对齐.但是,如果使用专用的对齐加载指令,例如

vmovaps ymm0,YMMWORD PTR [rax]
Run Code Online (Sandbox Code Playgroud)

必须对齐加载地址(为32的倍数),否则会引发异常.

令我困惑的是内在函数的自动代码生成,在我的例子中是gcc/g ++(4.6.3,Linux).请查看以下测试代码:

#include <x86intrin.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#define SIZE (1L << 26)
#define OFFSET 1

int main() {
  float *data;
  assert(!posix_memalign((void**)&data, 32, SIZE*sizeof(float)));
  for (unsigned i = 0; i < SIZE; i++) data[i] = drand48();
  float res[8]  __attribute__ ((aligned(32)));
  __m256 sum = _mm256_setzero_ps(), elem;
  for (float *d = data + OFFSET; d < data + SIZE - 8; d += 8) {
    elem = _mm256_load_ps(d);
    // …
Run Code Online (Sandbox Code Playgroud)

gcc avx avx2

12
推荐指数
1
解决办法
6959
查看次数

处理双数组的未对齐部分,向量化其余部分

我正在生成sse/avx指令,目前我必须使用未对齐的加载和存储.我在浮点/双数组上操作,我永远不知道它是否会对齐.所以在矢量化它之前,我希望有一个pre和可能的post循环,它关注未对齐的部分.然后,主矢量化循环在对齐的部分上操作.

但是我如何确定阵列何时对齐?我可以查看指针值吗?应该何时预循环停止和循环后启动?

这是我的简单代码示例:

void func(double * in, double * out, unsigned int size){
    for( as long as in unaligned part ){
        out[i] = do_something_with_array(in[i])
    }
    for( as long as aligned ){
        awesome avx code that loads operates and stores 4 doubles
    }
    for( remaining part of array ){
        out[i] = do_something_with_array(in[i])
    }
 }
Run Code Online (Sandbox Code Playgroud)

编辑:我一直在考虑它.从理论上讲,指向第i个元素的指针应该是可分的(类似于&a [i]%16 == 0)2,4,16,32(取决于它是否是双倍以及它是sse还是avx).所以第一个循环应该掩盖不可分割的元素.

实际上我将尝试编译器编译指示和标志输出,以查看编译器产生了什么.如果没有人给出一个好的答案,我会在周末发布我的解决方案(如果有的话).

c c++ x86 sse vectorization

9
推荐指数
1
解决办法
283
查看次数

OpenMP 4对齐选项?

我对OpenMP中的新对齐选项有疑问.这是在使用它的背景下#pragma omp simd aligned(a:n)

假设我有一个整数数组,我使用posix_memalign分配,所以我知道数组开始时让我们说32字节边界.现在让我说我想对该数组中的每个值进行平方.我能说......么...

int* array = { some array of length len aligned to 32 bytes };
#pragma omp simd aligned(array:32)
for(int i = 0; i < len; i++)
    array[i] *= array[i];
Run Code Online (Sandbox Code Playgroud)

这是一个安全的假设吗?或者对齐也暗示我在数组中使用的大小数据类型(int)是32个字节的倍数?有点像gcc中的属性((aligned(32))将使宽度类型至少为32个字节.

c c++ simd openmp

5
推荐指数
1
解决办法
2286
查看次数

为什么_mm256_load_pd编译为MOVUPD而不是MOVAPD?

为什么以下代码会导致未对齐的AVX指令(MOVUPD而不是MOVAPD)?我在Visual Studio 2015上编译了这个.如何告诉编译器我的数据确实是对齐的?

    const size_t ALIGN_SIZE = 64;
    const size_t ARRAY_SIZE = 1024;

    double __declspec(align(ALIGN_SIZE)) a[ARRAY_SIZE];
    double __declspec(align(ALIGN_SIZE)) b[ARRAY_SIZE];

    //Calculate the dotproduct
    __m256d ymm0 = _mm256_set1_pd(0.0);
    for (int i = 0; i < ARRAY_SIZE; i += 8)
    {
        __m256d ymm1 = _mm256_load_pd(a + i); 
        __m256d ymm2 = _mm256_load_pd(b + i);
        __m256d ymm3 = _mm256_mul_pd(ymm1, ymm2);
        ymm0 = _mm256_add_pd(ymm3, ymm0);

        __m256d ymm4 = _mm256_load_pd(a + i + 4);
        __m256d ymm5 = _mm256_load_pd(b + i + 4);
        __m256d ymm6 = _mm256_mul_pd(ymm4, ymm5); …
Run Code Online (Sandbox Code Playgroud)

c alignment avx visual-studio

5
推荐指数
1
解决办法
501
查看次数

标签 统计

c ×3

avx ×2

c++ ×2

alignment ×1

avx2 ×1

gcc ×1

openmp ×1

simd ×1

sse ×1

vectorization ×1

visual-studio ×1

x86 ×1