tutorial parallel for c++ multithreading loops openmp

c++ - parallel - Bucle paralelo paralelo con declaración de interrupción



openmp tutorial (6)

Aquí hay una versión más simple de la respuesta aceptada.

int ielement = -1; #pragma omp parallel { int i = omp_get_thread_num()*n/omp_get_num_threads(); int stop = (omp_get_thread_num()+1)*n/omp_get_num_threads(); for(;i <stop && ielement<0; ++i){ if(element[i]) { ielement = i; } } }

Sé que no se puede tener una declaración de interrupción para un bucle OpenMP, pero me preguntaba si hay alguna solución mientras aún se beneficia del paralelismo. Básicamente tengo ''for'' loop, que recorre los elementos de un vector grande buscando un elemento que satisfaga una determinada condición. Sin embargo, solo hay un elemento que satisfará la condición, de modo que una vez que se encuentre, podremos salir del ciclo, gracias de antemano

for(int i = 0; i <= 100000; ++i) { if(element[i] ...) { .... break; } }


Podría intentar hacer manualmente lo que hace el bucle de openmp for, usando un bucle while:

const int N = 100000; std::atomic<bool> go(true); uint give = 0; #pragma omp parallel { uint i, stop; #pragma omp critical { i = give; give += N/omp_get_num_threads(); stop = give; if(omp_get_thread_num() == omp_get_num_threads()-1) stop = N; } while(i < stop && go) { ... if(element[i]...) { go = false; } i++; } }

De esta manera tienes que probar "ir" cada ciclo, pero eso no debería importar mucho. Más importante es que esto correspondería a un bucle omp for "estático", que solo es útil, si puede esperar que todas las iteraciones tarden una cantidad de tiempo similar. De lo contrario, 3 subprocesos pueden estar listos, mientras que uno todavía tiene la mitad de ...


Probablemente lo haría (copiado un poco de yyfn)

volatile bool flag=false; for(int j=0; j<=100 && !flag; ++j) { int base = 1000*j; #pragma omp parallel for shared(flag) for(int i = 0; i <= 1000; ++i) { if(flag) continue; if(element[i+base] ...) { .... flag=true; } } }


Una forma de hacerlo es estableciendo i en un número que romperá el ciclo. Como tiene el bucle configurado para seguir funcionando mientras i ≤ 100000 , puede romper el bucle configurándolo en 100001 :

for(int i = 0; i <= 100000; ++i) { if(element[i] ...) { .... i = 100001; // break } }

Es posible que desee utilizar una solución más limpia, mientras que hace un bool indica si se rompe:

bool shouldBreak = false; for(int i = 0; i <= 100000 && !shouldBreak; ++i) { if(element[i] ...) { .... shouldBreak = true; } }


Ver este fragmento:

volatile bool flag=false; #pragma omp parallel for shared(flag) for(int i=0; i<=100000; ++i) { if(flag) continue; if(element[i] ...) { ... flag=true; } }

Esta situación es más adecuada para pthread.


bool foundCondition = false; #pragma omp parallel for for(int i = 0; i <= 100000; i++) { // We can''t break out of a parallel for loop, so this is the next best thing. if (foundCondition == false && satisfiesComplicatedCondition(element[i])) { // This is definitely needed if more than one element could satisfy the // condition and you are looking for the first one. Probably still a // good idea even if there can only be one. #pragma omp critical { // do something, store element[i], or whatever you need to do here .... foundCondition = true; } } }