c ++: OpenMP e contêineres STL de acesso não aleatório - uma possível solução alternativa
Então, no SO e nas Internets em geral, há muita confusão e frustração sobre como tornar o OpenMP fácil de usar#pragma
diretivas cooperam com os contêineres STL igualmente fáceis de usar do C ++.
Todo mundo fala sobre soluções para o STLvector
, mas o que acontece com o acesso não aleatório / recipientes bidirecionais, comomap
, list
, set
etc.?
Eu encontrei esse problema e planejei uma solução simples e óbvia. Eu apresento aqui para STLmap
, mas é claramente generalizável.
Versão serial:
<code>for (std::map<A,B>::iterator it = my_map.begin(); it != my_map.end(); ++it) { /* do work with it */ } </code>
Minha solução proposta para usar o OpenMP com 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>
Estou longe de ser um especialista em OpenMP, no entanto,Eu gostaria de saber se o meu trabalho proposto é eficiente e boa prática.
Por favor, assuma que o programador é responsável pela manipulação segura de thread do contêiner STL dentro do loop for.
Finalmente, a minha solução proposta é mais eficiente do que a seguinte solução comumente proposta(veja a resposta a esta pergunta do SO), porque, na minha solução, cada thread não itera todo o contêiner?
<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>