Jestem w trakcie uczenia się, jak korzystać z OpenMP w C, a jako ćwiczenie HelloWorld piszę program do liczenia liczb pierwszych. I wtedy parallelise to w następujący sposób:Równoległe pętle OpenMP z niewielkim wzrostem wydajności
int numprimes = 0;
#pragma omp parallel for reduction (+:numprimes)
for (i = 1; i <= n; i++)
{
if (is_prime(i) == true)
numprimes ++;
}
skompilować ten kod przy użyciu gcc -g -Wall -fopenmp -o primes primes.c -lm
(-lm
dla math.h
funkcji używam). Następnie uruchamiam ten kod na Intel® Core™2 Duo CPU E8400 @ 3.00GHz × 2
i zgodnie z oczekiwaniami wydajność jest lepsza niż w przypadku programu szeregowego.
Problem pojawia się jednak, gdy próbuję uruchomić to na znacznie potężniejszym komputerze. (Próbowałem również ręcznie ustawić liczbę wątków do korzystania z num_threads
, ale to niczego nie zmienia.) Licząc wszystkie liczby pierwsze do 10 000 000
daje mi następujących godzinach (przy użyciu time
): maszynę
8-core :
real 0m8.230s
user 0m50.425s
sys 0m0.004s
maszyna dwurdzeniowy:
real 0m10.846s
user 0m17.233s
sys 0m0.004s
a ten wzór trwa liczenie kolejne liczby pierwsze urządzenie z większą liczbą rdzeni pokazuje niewielki wzrost wydajności, ale nie tyle, ile by się spodziewać havin g więcej dostępnych rdzeni. (Spodziewam się 4 razy więcej rdzeni sugerować prawie 4 razy mniej czasu pracy?)
Zliczanie liczb pierwszych do 50 000 000
:
8-rdzeń maszyna:
real 1m29.056s
user 8m11.695s
sys 0m0.017s
dwurdzeniowy maszyny:
real 1m51.119s
user 2m50.519s
sys 0m0.060s
Jeśli ktoś może to dla mnie wyjaśnić, byłoby to bardzo cenne.
EDIT
To jest moja funkcja prime-checking.
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;
}
Jak wygląda twój 'is_prime'? Jeśli uzyska dostęp do danych udostępnionych między wątkami, spowoduje to narzut synchronizacji. –
'static int is_prime (int n)' jest nagłówkiem wywoływanej funkcji. Mogę dodać całą funkcję, jeśli pomoże to wyjaśnić problem. Sądzę, że każdy wątek automatycznie wywoływałby jego własną funkcję? – casper
Czy funkcja używa jakichkolwiek statycznych lub (pół) globalnych danych, czy używa tylko argumentu i stałych? –