2014-09-12 3 views
3

Я хочу использовать openmp для ускорения кода, как показано ниже.Как использовать openmp с перерывом в петле while

Код только для объяснения операций, а не реальных.

Iterator iterator(records); 
while(iterator.next()) 
{ 
    int current_id = iterator.current_row_index(); 
    bool result = index.find(records[current_id]) 
    if (result == false) 
     if (index.insert(records[current_id]) == false) 
      break; 
} 
return iterator.current_row_index(); 

Индекс является общим для всех потоков.

Вот некоторые мысли от меня:

  • с помощью директивы параллельного OMP, убедитесь, что потоки выполняются в порядке.
  • с использованием omp критической директивы для управления итератором.
  • с использованием omp критической директивы для поиска в индексе и вставки в индекс.

, но я действительно сомневаюсь в ускорении, поскольку почти вся операция находится в критическом состоянии.

Есть ли советы по ускорению использования кода с помощью openmp?

Спасибо!

+0

является итератором только передним итератором? Может ли он использоваться как итератор с произвольным доступом? – Anton

+0

@ Антон теперь только форвардный итератор, но я мог изменить его для поддержки назад. но он не может быть произвольным доступом. И я предпочитаю не изменять код итератора. – b8flowerfire

+0

Вы хотите остановить первый индекс, который был бы найден в цикле серийного цикла или в любом индексе? – Walter

ответ

4

Ответ на заголовок вопроса, и при условии, что не было никаких других проблем (обсуждается ниже), общее время как контур с перерывом над передним итератора может быть переведено так:

Iterator iterator(records); 
#pragma omp parallel 
{ 
    #pragma omp single nowait 
    { 
     while(iterator.next()) 
     { 
      int current_id = iterator.current_row_index(); 
      #pragma omp task firstprivate(current_id) 
      { 
       if (should_stop(current_id))) { 
        // below requires OpenMP 4.0 
        #pragma omp cancel parallel 
       } 
      } 
     } 
    } 
} 

Тем не менее, являются более сложными проблемами в вашем вопросе, которые действительно заслуживают отдельных вопросов.

  1. использование в index таблице свидетельствует о том, что она не поточно-. Таким образом, вы не можете безопасно получить к нему доступ и вставить одновременно. И поскольку это единственная работа для цикла while, нет смысла делать ее параллельной, если вы не переключитесь на параллельную хэш-таблицу, такую ​​как concurrent_unordered_map, представленную, например. , ,

  2. Неясно, когда вставка может вернуть значение false и почему вам нужен индекс строки, когда это произойдет. Вероятно, после перехода на другую реализацию таблицы это было бы совсем необязательно. В противном случае, как правило, несколько потоков могут иметь «ответ» на ваше состояние одновременно, и вы должны синхронизировать их и сводить к одному результату. Самый простой способ OMP-ish - использовать критический раздел для выбора и сохранения результата, в противном случае существует опасность введения в программу состояния гонки.

+0

'current_id' должен быть' firstprivate'. –

+0

Да, пропустил это, спасибо – Anton

+1

Вы также можете опустить предложение полностью, поскольку переменные 'private' являются' firstprivate' по умолчанию при использовании в конструкциях 'task'. –

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