ICC сокращается медленно и дает неправильные результаты
Я пытаюсь написать простой код сокращения для сопроцессора Xeon Phi, используя Intel Compiler (ICC). Однако у моего кода есть две проблемы: первая проблема в том, что он дает неправильный результат, и он медленнее, чем последовательное решение. Я скомпилировал код с этими параметрами (mpi_reduce.c - это имя файла):
icc mpi_reduce.c -V -openmp -o mpi_reduce.out
Вот мой код:
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
float * _Cilk_shared data; //pointer to “shared” memory
_Cilk_shared float MIC_OMPReduction(int size)
{
int i;
#ifdef __MIC__
float Result;
int nThreads = 32;
omp_set_num_threads(nThreads);
#pragma omp parallel for reduction(+:Result)
for (i=0; i<size; ++i)
{
Result += data[i];
}
return Result;
#else
printf("Intel(R) Xeon Phi(TM) Coprocessor not available\n");
#endif
return 0.0f;
}
float reduction_serial(int size)
{
float ret = 0;
int i;
for ( i=0; i<size; ++i)
{
ret += data[i];
}
return ret;
}
int main()
{
struct timeval tv1, tv2;
int sec, usec;
int i;
float result_serial, result_parallel;
size_t size = 1*1e6;
int n_bytes = size*sizeof(float);
data = (_Cilk_shared float *)_Offload_shared_malloc (n_bytes);
printf("begin computation for size: %d \n",size);
for (i=0; i<size; ++i)
{
data[i] = i%10;
}
gettimeofday(&tv1,NULL);
result_serial = reduction_serial(size);
gettimeofday(&tv2,NULL);
sec = (int) (tv2.tv_sec-tv1.tv_sec);
usec = (int) (tv2.tv_usec-tv1.tv_usec);
if (usec < 0){
sec--;
usec += 1000000;
}
printf("reduction_serial: %f sec\n",sec+usec/1000000.0);
printf("reduction_serial result = %f \n",result_serial);
gettimeofday(&tv1,NULL);
result_parallel = _Cilk_offload MIC_OMPReduction(size);
gettimeofday(&tv2,NULL);
sec = (int) (tv2.tv_sec-tv1.tv_sec);
usec = (int) (tv2.tv_usec-tv1.tv_usec);
if (usec < 0){
sec--;
usec += 1000000;
}
printf("reduction_parallel: %f sec\n",sec+usec/1000000.0);
printf("reduction_parallel result = %f \n",result_parallel);
_Offload_shared_free(data);
return 0;
}
И вот это вывод моего кода:
begin computation for size: 1000000
reduction_serial: 0.000239 sec
reduction_serial result = 4500000.000000
reduction_parallel: 0.461872 sec
reduction_parallel result = 4513334.000000
Я заметил, что когда я компилирую код без опции -openmp, результат параллельного кода будет правильным, однако с использованием опции -openmp результат будет неправильным.