2011-12-24 19 views
7

mam dla pętli w moim kodu C, co następuje:parallelizing dla pętli w C

for(i=0; i<100000; i++){ 

    a[i] = simulate(); // simulate() function simulates some system 

} 

Widzimy, że obliczenie każdej iteracji jest niezależna od innych (kolejność elementów w a[] nie jest ważne mnie). Chcę zrównoważyć obliczenia tej pętli for za pomocą wielowątkowości. Nie jestem dokładnie świadomy, jak to zrobić w C? Mam 8 procesorów, więc mogę równolegle uruchomić 8 wątków.

Odpowiedz

11

Nie ma przenośnego sposobu na równoległość w C *. Jednak OpenMP standard jest powszechnie obsługiwana:

#pragma omp parallel for 
for(i=0; i<100000; i++){ 

    a[i] = simulate(); // simulate() function simulates some system 

} 

zależności od kompilatora, nie będzie flag, które trzeba ustawić, aby umożliwić OpenMP wsparcia:

  • MSVC:/openmp
  • GCC :-fopenmp

, jak nagłówek, jeśli chcesz uzyskać dostęp do pewnych funkcji OpenMP:

#include <omp.h> 

EDIT:

* (bardzo niedawno zatwierdzony) norma C11 posiada wsparcie dla wątków poprzez <threads.h>.

+1

'Nie ma przenośnego sposobu na równoległość w C' Nowy standard C11 ma teraz tylko kilka dni, ale to się zmienia! – u0b34a0f6ae

+0

@ kaizer.se Woah, nie zdawałem sobie sprawy, że C11 został zatwierdzony! Wspomnę o tym w mojej odpowiedzi. Dzięki! – Mysticial

+0

Dzięki za odpowiedź. Próbowałem tego. Dla niektórych [i] otrzymuję "nan" lub "-nan", chociaż kod działa poprawnie, gdy jest wykonywany seryjnie. Myślę, że może być jakiś problem z synchronizacją. –

0

Jeśli twój kompilator obsługuje standard C11, w szczególności stdatomic.h, możesz to zrobić.

Poniżej znajduje się prosty przykład, który powinien dać ci podstawową ideę. To nie jest trudne. Ten używa wątków POSIX, ale powinieneś być w stanie użyć dowolnej biblioteki wątków.

#include <stdio.h> 
#include <stdatomic.h> 
#include <pthread.h> 

#define ELEMENTS_N 500000 

_Atomic unsigned int x; 
unsigned int N; 
unsigned int anyArray[ELEMENTS_N]; 

void * ThreadLoop (void * args) 
{ 
    unsigned int l; 
    while((l = atomic_load(&x)) < N) 
    { 
    if (atomic_compare_exchange_weak(&x, &l, l + 1)) 
    { 
     anyArray[l] = l; 
    } 
    } 
    return 0; 
} 


int main (int argc, char *argv[]) 
{ 

    pthread_t th1; 
    pthread_t th2; 
    int v; 

    atomic_store(&x, 0); 
    N = ELEMENTS_N; 

    v = pthread_create(&th1, NULL, &ThreadLoop, NULL); 
    v = pthread_create(&th2, NULL, &ThreadLoop, NULL); 

    pthread_join(th1, NULL); 
    pthread_join(th2, NULL); 

    for(v = 0; v < ELEMENTS_N; v++) 
    { 
    printf("%d ", anyArray[v]); 
    } 

    return 0; 
}