Мне нужно объединить два массива с OpenMP.Идея состоит в том, чтобы разбить массивы на p сегментов с помощью совместного ранжирования (где p - количество процессоров), а затем дать каждому процессору из этих сегментов объединиться.
Проблема в том, что привсе по сравнению с непараллельным слиянием двух массивов.
Я проверил, верны ли границы, в которых разбиваются массивы a
и b
, и, насколько я понимаю, так и есть.Функция coRank
ранжирует значение a
в c
в b
и a
, и, насколько я понимаю, это кажется правильным и не должно вызывать проблему.Если мы посмотрим на использование ЦП диспетчера задач Windows, все ядра ЦП имеют одинаковый всплеск при запуске программы, поэтому я предполагаю, что все ЦП действительно что-то делают.Объединенный массив является правильным, но он занимает столько же времени, сколько и последовательное слияние.
void merge(array_t a[], long x, array_t b[], long y, array_t c[]) {
//split the a and b arrays with co-ranking
int cores = omp_get_max_threads();
long *startsInA = (long *)malloc(sizeof(long) * cores);
long *startsInB = (long *)malloc(sizeof(long) * cores);
#pragma omp parallel for
for(int i = 0; i < cores; i++){
coRank((i*(x+y)/cores),a,x,b,y,&startsInA[i],&startsInB[i]);
}
//do a sequential merge for each segment-pair
#pragma omp parallel private(a,b)
{
int index = omp_get_thread_num();
long lowerBoundA = startsInA[index];
long lowerBoundB = startsInB[index];
int upperBoundA;
int upperBoundB;
if(index < cores - 1){
upperBoundA = startsInA[index+1];
upperBoundB = startsInB[index+1];
} else {
upperBoundA = x;
upperBoundB = y;
}
seq_merge1((a+lowerBoundA),upperBoundA-lowerBoundA, (b+lowerBoundB),upperBoundB-lowerBoundB,c+lowerBoundA+lowerBoundB);
}
free(startsInA);
free(startsInB);
}
Вывод функции слияния правильный, но он должен быть быстрее, чем последовательное слияние, а это не так.