Работа с параллельным битом на основе первого поиска с помощью openMP?

55
7

Недавно я изучал C++. И простое средство поиска чисел - это упражнение. После того, как я написал код серийной версии, я попытался использовать openmp для распараллеливания кода. Тем не менее, серийная версия работает нормально, но как только я попробовал версию openmp, вывод (простые числа от 1 до 100) является очень неправильным. Любое предложение?

Вот мой код (относительные функции):

    void prime2_bits(const int& n)
{
omp_set_num_threads(4);
int i,j,tp,sq=sqrt(n+1);
int p[n/32+1];
initint(p,n/32+1);
#pragma omp parallel for default(shared) private(i,j,tp) schedule(dynamic)
for(i=2;i<sq;i++){
if(!((p[i/32]>>(i%32))&1)){ // see whether the ith bit is 0
tp=i*i;
for(j=tp;j<n+1;j+=i){
p[j/32]|=(1<<(j%32)); // set the jth bit as 1
}
}
}
// Do the printing job
for(i=2;i<n+1;i++)
if(!((p[i/32]>>(i%32))&1)) cout<<i<<' ';
}

и вывод выглядит следующим образом:

using method 2 (bits to save space):
2 3 5 7 11 13 15 17 19 21 23 27 29 31 35 37 41 43 47 49 53 55 59 61 67 69 71 73 77 79 81 83 87 89 91 93 97 99 0 msec used!

Кроме того, чтобы повысить эффективность, я снова изменил серийный код. Затем попытался провести параллель с openmp без успеха. Любое предложение для этого?

измененный код:

void prime3_norev(const int& n)
{
int i,j,tp,m=n+1;
int pi=0;
bool pFlag[m];
int p[n/3];
omp_set_num_threads(4);
initbool(pFlag,m);
initint(p,n/3);
#pragma omp parallel for default(shared) private(i,j) schedule(dynamic)
for(i=2;i<m;i++){
if(!pFlag[i]) p[pi++]=i;
for(j=0;(j<pi)&&(i*p[j]<m);j++){
pFlag[i*p[j]]=true;
if(i%p[j]==0) break;
}
}
// Do the printing job
for(i=0;i<pi;i++)
cout<<p[i]<<' ';
}

и соответствующий выход:

using method 3 (no revisits, space for time):
2 3 6 7 11 13 15 19 23 29 31 35 37 41 43 47 53 55 59 61 65 67 71 73 79 83 85 89 95 97 0 msec used!

Код был скомпилирован с помощью:

g++ -O2 -fopenmp fib.cc

Большое спасибо!

спросил(а) 2014-04-04T10:01:00+04:00 6 лет, 3 месяца назад
1
Решение
55

Чтобы исправить ваш код, вы можете использовать упорядоченное предложение

#pragma omp parallel for schedule(dynamic) ordered
for(int i=2;i<m;i++) {
#pragma omp ordered
if(!pFlag[i]) p[pi++]=i;
//rest of code

Для рабочего примера см. Http://coliru.stacked-crooked.com/a/fa1eebf126940fb0. Я использовал расписание (статические) там, чтобы просто показать ошибку без упорядоченного предложения.

Я не уверен, какой эффект заказал бы на производительность. Мне кажется, что вы пытаетесь распараллелить Сито Эратосфена. В этом случае я предлагаю вам ознакомиться с http://create.stephan-brumme.com/eratosthenes/. Он находит все простые числа до 10 ^ 9 примерно за 1 секунду, используя OpenMP.

ответил(а) 2014-04-04T11:04:00+04:00 6 лет, 3 месяца назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема