Я изучаю, как использовать OpenMP в C, и в качестве упражнения HelloWorld я пишу программу для подсчета простых чисел. Я тогда parallelise это следующим образом:OpenMP Parallel for-loop показывает небольшое увеличение производительности
int numprimes = 0;
#pragma omp parallel for reduction (+:numprimes)
for (i = 1; i <= n; i++)
{
if (is_prime(i) == true)
numprimes ++;
}
Я скомпилировать этот код, используя gcc -g -Wall -fopenmp -o primes primes.c -lm
(-lm
для math.h
функций я использую). Затем я запускаю этот код на Intel® Core™2 Duo CPU E8400 @ 3.00GHz × 2
, и, как и ожидалось, производительность лучше, чем для последовательной программы.
Проблема, однако, возникает, когда я пытаюсь запустить ее на гораздо более мощной машине. (Я также попытался вручную установить количество потоков для использования с num_threads
, но это ничего не меняет.) Подсчет всех простых чисел до 10 000 000
дает мне следующее время (с помощью time
):
8-жильных машины :
real 0m8.230s
user 0m50.425s
sys 0m0.004s
двухъядерный машина:
real 0m10.846s
user 0m17.233s
sys 0m0.004s
И эта картина продолжается подсчет более простых чисел, машина с большим количеством ядер показывает небольшое увеличение производительности, но не так много, как хотелось бы ожидать Хавин g доступно еще столько ядер. (Я бы ожидать, в 4 раза больше ядер подразумевает почти в 4 раза меньше времени пробега?)
Counting воспламеняет до 50 000 000
:
8-ядро машины:
real 1m29.056s
user 8m11.695s
sys 0m0.017s
двухъядерный машина:
real 1m51.119s
user 2m50.519s
sys 0m0.060s
Если кто-нибудь может прояснить это для меня, было бы очень признательно.
EDIT
Это моя функция прайм-проверка.
static int is_prime(int n)
{
/* handle special cases */
if (n == 0) return 0;
else if (n == 1) return 0;
else if (n == 2) return 1;
int i;
for(i=2;i<=(int)(sqrt((double) n));i++)
if (n%i==0) return 0;
return 1;
}
Как выглядит ваш 'is_prime'? Если это обращается к данным, разделяемым между потоками, это вызовет накладные расходы синхронизации. –
'static int is_prime (int n)' - это заголовок вызываемой функции. Я могу добавить всю функцию, если это поможет прояснить проблему. Я бы подумал, что каждый поток автоматически вызовет свою собственную функцию? – casper
Использует ли функция какие-либо статические или (полу) глобальные данные или использует только аргумент и константы? –