Я пытаюсь создать простую программу, которая использует технологию Intel AVX и выполняет умножение и сложение векторов. Здесь я использую Open MP вместе с этим. Но происходит ошибка сегментации из-за вызова функции _mm256_store_ps ().
Я пробовал использовать атомарные функции OpenMP, такие как атомарные, критические и т. Д., Так что если эта функция атомарна по своей природе и несколько ядер пытаются выполняться одновременно, но она не работает.
#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
- Процессор Intel® Core ™ 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