Запустите приведенный ниже код и увидите разницу.
1.) У OpenMP есть издержки, поэтому время выполнения должно быть больше, чем издержки, чтобы увидеть преимущество.
2.) Не устанавливайте количество потоков самостоятельно.В общем, я использую темы по умолчанию.Однако, если ваш процессор имеет гиперпоточность, вы можете получить немного лучшую производительность, установив число потоков, равное количеству ядер.При гиперпоточности число потоков по умолчанию будет вдвое больше количества ядер.Например, на моей машине у меня четыре ядра, а число потоков по умолчанию - восемь.Установив значение 4 в некоторых ситуациях, я получаю лучшие результаты, а в других - худшие результаты.
3.) Существует некоторое ложное разделение в c, но пока N
достаточно велико (чтонеобходимо преодолеть накладные расходы) ложное разделение не вызовет особых проблем.Вы можете играть с размером чанка, но я не думаю, что это будет полезно.
4.) Проблемы с кэшем.У вас есть как минимум четыре уровня памяти (значения для моей системы): L1 (32 КБ), L2 (256 КБ), L3 (12 МБ) и основная память (>> 12 МБ).Преимущества параллелизма будут уменьшаться по мере перехода на более высокий уровень.Однако в приведенном ниже примере я установил N на 100 миллионов операций с плавающей запятой, что составляет 400 миллионов байтов или около 381 МБ, и это все еще значительно быстрее при использовании нескольких потоков.Попробуйте настроить N
и посмотрите, что произойдет.Например, попробуйте установить N
на уровень кеша / 4 (один float равен 4 байта) (массивы a и b также должны находиться в кеше, поэтому вам может потребоваться установить N на уровень кеша / 12).Однако, если N
слишком мало, вы боретесь с издержками OpenMP (что и делает код в вашем вопросе).
#include <stdio.h>
#include <omp.h>
#define N 100000000
int main(int argc, char *argv[]) {
float *a = new float[N];
float *b = new float[N];
float *c = new float[N];
int i;
for (i = 0; i < N; i++) {
a[i] = i * 1.0;
b[i] = i * 2.0;
}
double dtime;
dtime = omp_get_wtime();
for (i = 0; i < N; i++) {
c[i] = a[i] + b[i];
}
dtime = omp_get_wtime() - dtime;
printf ("time %f, %f\n", dtime, c[10]);
dtime = omp_get_wtime();
#pragma omp parallel for private(i)
for (i = 0; i < N; i++) {
c[i] = a[i] + b[i];
}
dtime = omp_get_wtime() - dtime;
printf ("time %f, %f\n", dtime, c[10]);
return 0;
}