У меня есть цикл for, который использует (несколько сложный) объект-счетчик sp_ct
для инициализации массива. Серийный код выглядитЭлегантная инициализация потоков openmp параллельно для цикла
sp_ct.depos(0);
for(int p=0;p<size; p++, sp_ct.increment()) {
in[p]=sp_ct.parable_at_basis();
}
Мой счетчик поддерживает распараллеливание, поскольку он может быть инициализирован в состояние после p
приращений, что приводит к следующему рабочему кодового фрагмента:
int firstloop=-1;
#pragma omp parallel for \
default(none) shared(size,in) firstprivate(sp_ct,firstloop)
for(int p=0;p<size;p++) {
if(firstloop == -1) {
sp_ct.depos(p); firstloop=0;
} else {
sp_ct.increment();
}
in[p]=sp_ct.parable_at_basis();
} // end omp paralell for
Мне не нравится это из-за беспорядок, который скрывает то, что действительно происходит, и потому что у него есть ненужная ветвь внутри цикла. (Да, я знаю, что это, вероятно, не окажет заметного влияния на время работы, потому что это , так что предсказуемо ...).
Я бы предпочел, чтобы написать что-то вроде
#pragma omp parallel for default(none) shared(size,in) firstprivate(sp_ct,firstloop)
for(int p=0;p<size;p++) {
#prgma omp initialize // or something
{ sp_ct.depos(p); }
in[p]=sp_ct.parable_at_basis();
sp_ct.increment();
}
} // end omp paralell for
Возможно ли это?
Есть ли причина, по которой вы не можете выполнить инициализацию вне цикла? –
Да, инициализация зависит от первого значения 'p', которое назначено потоку. Это неизвестно вне цикла. –