У меня есть этот серийный код:OpenMP: Упорядоченный график (статический) Кусок последовательность
std::vector<T> input, output;
//populate input
for (size_t i=0 ; i < input.size() ; i++){
output.push_back(//something using input[i]);
}
Заметьте, что это важно, что output[i]
вычисляется с использованием input[i]
. Теперь я хочу распараллелить его. Простым решением является:
std::vector<T> input, output;
//populate input
#pragma omp for schedule(dynamic) ordered
for (size_t i=0 ; i < input.size() ; i++){
#pragma omp ordered
output.push_back(//something using input[i]);
}
Однако, это может быть очень неэффективным (ordered
требует, чтобы получить замок, который генерирует большую нагрузку, если выполняется много раз, и, кроме того, если размер порции небольшие это порождает еще больше накладных расходов). Другим возможным решением может быть заполнить каждый кусок по отдельности, а затем объединить их (в упорядоченном пути):
std::vector<T> input, output;
//populate input
#pragma omp parallel
{
std::vector<T> myOutput;
std::vector<int> myIndexes;
#pragma omp for schedule(static,1) //NOTICE STATIC!
for (size_t i=0 ; i < input.size() ; i++){
myOutput.push_back(//something using input[i]);
myIndexes.push_back[i];
}
#pragma omp for ordered schedule(static)
for(int i=0 ; i<omp_get_num_threads() ; i++){
#pragma omp ordered
{
std::cout<<"Hello from thread "<<omp_get_thread_num()<<": ";
for(size_t j = 0; j < myIndexes.size(); j++)
std::cout<<indexes[j]<<" ";
std::cout<<std::endl;
}
}
}
Предположив, что input.size()=10
и у нас есть 8 ядер. Это то, что я хочу быть распечатаны:
Hello from thread 0: 0 1
Hello from thread 1: 2 3
Hello from thread 2: 4
Hello from thread 3: 5
Hello from thread 4: 6
Hello from thread 5: 7
Hello from thread 6: 8
Hello from thread 7: 9
Но это является то, что он на самом деле напечатал:
Hello from thread 0: 0 8
Hello from thread 1: 1 9
Hello from thread 2: 2
Hello from thread 3: 3
Hello from thread 4: 4
Hello from thread 5: 5
Hello from thread 6: 6
Hello from thread 7: 7
Код в this вопрос может решить мой случай, но это своего рода обман (это фактически не используя #pragma omp parallel for
).
Возможно ли получить желаемое поведение, используя только openmp?
Вы попробовали 'schedule (static, 2)' вместо 1? – Gilles
Нет, но это не имеет значения: в этом случае вам просто нужно три элемента на поток, которые мы находимся в той же ситуации до – justHelloWorld