【发布时间】:2019-05-02 13:21:51
【问题描述】:
我正在尝试创建一个使用英特尔 AVX 技术并执行向量乘法和加法的简单程序。在这里,我正在使用 Open MP。但由于函数调用 _mm256_store_ps() 导致分段错误。
我已经尝试过使用 OpenMP 的原子特性,如 atomic、critical 等,如果这个函数本质上是原子的,并且多个内核试图同时执行,但它不起作用。
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#include<immintrin.h>
#include<omp.h>
#define N 64
__m256 multiply_and_add_intel(__m256 a, __m256 b, __m256 c) {
return _mm256_add_ps(_mm256_mul_ps(a, b),c);
}
void multiply_and_add_intel_total_omp(const float* a, const float* b, const float* c, float* d)
{
__m256 a_intel, b_intel, c_intel, d_intel;
#pragma omp parallel for private(a_intel,b_intel,c_intel,d_intel)
for(long i=0; i<N; i=i+8) {
a_intel = _mm256_loadu_ps(&a[i]);
b_intel = _mm256_loadu_ps(&b[i]);
c_intel = _mm256_loadu_ps(&c[i]);
d_intel = multiply_and_add_intel(a_intel, b_intel, c_intel);
_mm256_store_ps(&d[i],d_intel);
}
}
int main()
{
srand(time(NULL));
float * a = (float *) malloc(sizeof(float) * N);
float * b = (float *) malloc(sizeof(float) * N);
float * c = (float *) malloc(sizeof(float) * N);
float * d_intel_avx_omp = (float *)malloc(sizeof(float) * N);
int i;
for(i=0;i<N;i++)
{
a[i] = (float)(rand()%10);
b[i] = (float)(rand()%10);
c[i] = (float)(rand()%10);
}
double time_t = omp_get_wtime();
multiply_and_add_intel_total_omp(a,b,c,d_intel_avx_omp);
time_t = omp_get_wtime() - time_t;
printf("\nTime taken to calculate with AVX2 and OMP : %0.5lf\n",time_t);
}
free(a);
free(b);
free(c);
free(d_intel_avx_omp);
return 0;
}
我希望我会得到 d = a * b + c 但它显示分段错误。我试图在没有 OpenMP 的情况下执行相同的任务,并且它可以正常工作。如果有任何兼容性问题或我缺少任何部分,请告诉我。
- gcc 版本 7.3.0
- 英特尔® 酷睿™ i3-3110M 处理器
- 操作系统 Ubuntu 18.04
- 打开 MP 4.5,我执行了命令
$ echo |cpp -fopenmp -dM |grep -i open,它显示#define _OPENMP 201511 - 编译命令,
gcc first_int.c -mavx -fopenmp
** 更新 **
根据讨论和建议,新代码是,
float * a = (float *) aligned_alloc(N, sizeof(float) * N);
float * b = (float *) aligned_alloc(N, sizeof(float) * N);
float * c = (float *) aligned_alloc(N, sizeof(float) * N);
float * d_intel_avx_omp = (float *)aligned_alloc(N, sizeof(float) * N);
这工作不完美。
请注意,我试图比较一般计算、avx 计算和 avx+openmp 计算。这是我得到的结果,
- 不使用 AVX 的计算时间:0.00037
- 用 AVX 计算所用时间:0.00024
- 使用 AVX 和 OMP 计算所需的时间:0.00019
N = 50000
【问题讨论】:
-
请发minimal reproducible example 以帮助我们更好地了解您的问题。
-
平台?编译器?选项? OpenMP 版本?
-
@P.W 我已经修改了代码,请看一下。
-
@SeverinPappadeux 我已包含您所询问的信息。请看一看。
-
不,它不能保证是原子的,但实际上它在某些 CPU 上。见和SSE instructions: which CPUs can do atomic 16B memory operations?Per-element atomicity of vector load/store and gather/scatter?。不过,您的问题主体是关于调试段错误的;我看不出与询问 32 字节存储的原子性有什么联系。