c ++: OpenMP и контейнеры STL без произвольного доступа - возможный обходной путь
Таким образом, в SO и Интернет-сетях в целом существует много путаницы и разочарований по поводу того, как сделать OpenMP простым в использовании.#pragma
директивы взаимодействуют с одинаково простыми в использовании контейнерами STL в C ++.
Все говорят об обходных путях для STLvector
, но как насчет контейнеров с произвольным доступом / двунаправленнымmap
, list
, set
, так далее. ?
Я столкнулся с этой проблемой и изобрел очень простой, очевидный обходной путь. Я представляю это здесь для STLmap
, но это явно обобщаемо.
Серийная версия:
<code>for (std::map<A,B>::iterator it = my_map.begin(); it != my_map.end(); ++it) { /* do work with it */ } </code>
Мое предлагаемое решение использовать OpenMP с STLmap
:
<code> //make an array of iterators. int loop_length = my_map.size(); std::map<A,B>::iterator loop_array[ loop_length ]; std::map<A,B>::iterator allocate_it = my_map.begin(); for (int j=0; j<loop_length; ++j) loop_array[j] = allocate_it++; // now you can use OpenMP as usual: #pragma omp parallel for for (uint j=0; j<loop_length; ++j) { /* do work with loop_array[j] */ } </code>
Я далеко не эксперт по OpenMP, однако, такI would like to know if my proposed work-around is efficient and good practice.
Пожалуйста, предположим, что программист отвечает за поточно-ориентированную обработку контейнера STL в цикле for.
Наконец, мое предложенное решение более эффективно, чем следующее обычно предлагаемое решение(см. ответ на этот вопрос), потому что, в моем решении, каждый поток не перебирает весь контейнер?
<code>#pragma omp parallel { for (std::map<A,B>::iterator it = my_map.begin(); it != my_map.end(); ++it) #pragma single nowait { /* do work */ } } </code>