Я тестирую ускорения параллельной программы на C с использованием OpenMP. Используя флаг -O3 для компиляции кода с gcc, время выполнения кажется намного меньшим. Тем не менее, я постоянно получаю более медленные ускорения для разных номеров потоков (2,4,8,16,24) по сравнению с кодом, скомпилированным без флагов оптимизации. Как это возможно?Флаг оптимизации O3, делающий ускорения хуже в параллельной обработке
Подробнее о том, что я нашел до сих пор. Я пишу код для нахождения простых чисел на основе Sieve of Eratosthenes и пытаюсь оптимизировать его с помощью параллельной версии с использованием OpenMP. Вот код
#include <stdio.h>
#include <stdlib.h>
#include <omp.h>
#include <math.h>
// ind2num: returns the integer (3<=odd<=numMax)
// represented by index i at prime_numbers (0<=i<=maxInd)
#define ind2num(i) (2*(i)+3)
// num2ind: retorns the index (0<=i<=maxInd) at prime_numbers
// which represents the number (3<=odd<=numMax)
#define num2ind(i) (((i)-3)/2)
// Sieve: find all prime numbers until ind2num(maxInd)
void Sieve(int *prime_numbers, long maxInd) {
long maxSqrt;
long baseInd;
long base;
long i;
// square root of the largest integer (largest possible prime factor)
maxSqrt = (long) sqrt((long) ind2num(maxInd));
// first base
baseInd=0;
base=3;
do {
// marks as non-prime all multiples of base starting at base^2
#pragma omp parallel for schedule (static)
for (i=num2ind(base*base); i<=maxInd; i+=base) {
prime_numbers[i]=0;
}
// updates base to next prime number
for (baseInd=baseInd+1; baseInd<=maxInd; baseInd++)
if (primos[baseInd]) {
base = ind2num(baseInd);
break;
}
}
while (baseInd <= maxInd && base <= maxSqrt);
}
Если я исполню его, чтобы найти все простые числа меньше, чем 1000000000 (10^9), к примеру, я в конечном итоге со следующим временем выполнения для различного числа нитей (1,2, 4,8,16,24):
Без -O3 | 56.31s | 28.87s | 21.77s | 11.19s | 6.13s | 4.50s |
С -O3 .... | 10.10s | 5.23s | 3.74s | 2.81s | 2.62s | 2.52s |
Вот соответствующие скорости окна:
Без -O3 | 1 | 1.95 | 2,59 | 5,03 | 9.19 | 12.51 |
С -O3 .... | 1 | 1.93 | 2.70 | 3,59 | 3,85 | 4.01 |
Почему я продолжаю получать более низкие ускорения с флагом -O3?
@ user3386109, он распараллеливает процесс вычеркивания кратных заданного штриха из сита (ищите '#pragma omp'). –
Как вы вычисляете время и что представляют цифры (например, diff 'clock_gettime')? Он выглядит как (например,) для 24, без '-O3' составляет 4,5 с, а с 2,52 с (то есть с увеличением ~ 2x быстрее). Вы подтвердили, что _results_ одинаковы для всех # потоков? То есть, никакое условие гонки в модификации «primos». Кроме того, помимо ~ 4 потоков, вы можете насытить шину памяти доступом к «primos», и это ограничивающий фактор, независимо от количества ядер. –
Для каждого количества потоков время выполнения оптимизированного кода «-O3» ниже, чем время выполнения оптимизированного по умолчанию кода. Вот о чем вы должны смотреть. Нет причин предполагать, что ускорение с увеличением количества строк должно быть одинаковым для одного случая, а для другого - сравнение ускорений * разных программ *. –