2016-12-14 2 views
0

Как правильно распараллелить внутренний контур:.вложенная параллельно OMP v 2,0 производительность

int found = -1; 
#pragma omp parallel for ordered schedule(dynamic, 1) shared(found) 
for (long i = 0; i < big_number; ++i) 
{ 
    if(function()) 
    { 
    #pragma omp ordered 
    if(found == -1) 
    { 
     found = i; 
    } 
    } 
} 

bool function() 
{ 
    for(int i =0; i < another_big_number; i++) 
    { 
    if(some_condition) 
    { 
     return true; 
    } 
    } 
} 

Я не могу отправить весь код, но я все наиболее часть, которая, кажется, необходимо ответить на этот вопрос. Идея первого цикла - найти самую низкую итерацию, возвращаемую функцией true.

EDIT: конечно любая идея о повышении распараллеливания ценятся, однако, на мой вопрос о том, как я могу улучшить производительность функции() себя наряду с наружным для цикла с использованием вложенной методологии.

Обратите внимание, что я знаю предложение collapse, однако я не могу его использовать (благодаря визуальной студии, которая не поддерживает более поздние версии openMP).

Оценивается любая идея для улучшения всей параллельной петли. :)

Как вы думаете, будет ли увеличение производительности путем параллелизации цикла for внутри функции()?

+0

ли вы попробовать firstprivate (найдено) lastprivate (Fou nd), чтобы избавиться от общих и omp заказанных (что может не избежать гонки)? – tim18

+0

Функция() может быть лучше оптимизирована с помощью simd, но для этого потребуются встроенные функции SSE/AVX, если вы должны придерживаться компилятора Microsoft. – tim18

+0

Возможный дубликат [find \ _first параллельного параллелизма в C++] (http://stackoverflow.com/questions/40285046/find-first-of-a-vector-in-parallel-in-c) – Zulan

ответ

1

Этот код имеет много проблем, сначала вы не можете заколевать петлю таким образом (return found), тем более этот порядок не имеет особого смысла, по крайней мере, с куском кода, который вы предоставили, используйте flush do реализовать перерыв цикла, что-то вроде:

boolean found = false; 
long return_value = -1; 

#pragma omp parallel for schedule(dynamic, 1) shared(found, return_value) 
for (long i = 0; i < big_number; ++i) 
{ 
    #pragma omp flush (found) 
    if(!found) 
    { 
     if(function()){ 
     found = true; 
     return_value = i; 
     #pragma omp flush (found) 

     } 
    } 
} 

или также:

long return_value = -1; 

#pragma omp parallel for schedule(dynamic, 1) shared(return_value) 
for (long i = 0; i < big_number; ++i) 
{ 
    if(function()){ 

     #pragma omp critical 
     { 
      return_value = i; 
     } 

     #pragma omp cancel for 
     } 
    #pragma omp cancellation point for 
} 

на примере из here

+0

Спасибо за ваш ответ, как вы можете убедиться, что будет, например. , два потока внутри условия if, младший номер итерации присваивается return_value? –

+0

Поскольку свойство return_value является общим, вы можете внутри критического сравнения if (i dreamcrash

+0

Мне интересно, поддерживает ли директива cancel OpenMP v. 2.0. Поскольку я уже упоминал, что визуальная студия не поддерживает более поздние версии openMP –

Смежные вопросы