c++ - openMP 无效控制谓词
问题描述
在这段代码中,我正在尝试使用 OpenMP 并行执行 Sieve of Eratosthenes 算法,当程序是串行的时它工作正常
for (int i = p * p; i <= n; i += p) 素数[i] = false;
但是当我使用
#pragma omp for
它给出了这个错误
错误:无效的控制谓词 17 | for (int p = 2; p * p <= n; p++)
这是代码
#include <bits/stdc++.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <omp.h>
using namespace std;
void SieveOfEratosthenes(int n)
{
#pragma omp parallel
{
bool prime[n + 1];
memset(prime, true, sizeof(prime));
#pragma omp for
for (int p = 2; p * p <= n; p++)
{
if (prime[p] == true)
{
for (int i = p * p; i <= n; i += p)
prime[i] = false;
}
}
#pragma omp critical
for (int p = 2; p <= n; p++)
if (prime[p])
printf("%d ", p);
}
}
int main()
{
printf("Enter the siza: ");
int n ;
scanf("%d", &n);
printf("Following are the prime numbers from 1 to %f \n", sqrt(n));
SieveOfEratosthenes(sqrt(n));
printf("\n");
return 0;
}
解决方案
正如@Daniel Langr 所指出的,您的循环测试形式不受支持。它必须是规范的循环形式。有关更多详细信息,请参阅OpenMP 规范的2.9.1 规范循环形式。取比较两边的平方根,您可以将其更改为支持的形式:
const int end_p=sqrt(n);
#pragma omp for
for (int p = 2; p <= end_p; p++)
请注意,您的代码也有其他错误:每个线程将创建一个私有prime
数组并处理其私有副本,因此您会获得不正确的结果。您可以通过使用共享prime
数组和原子读写操作来纠正它:
void SieveOfEratosthenes(int n)
{
bool prime[n + 1];
memset(prime, true, sizeof(prime));
const int end_p=sqrt(n);
#pragma omp parallel for
for (int p = 2; p <= end_p; p++)
{
bool prime_p;
#pragma omp atomic read
prime_p=prime[p];
if (prime_p == true)
{
for (int i = p * p; i <= n; i += p)
{
#pragma omp atomic write
prime[i] = false;
}
}
}
for (int p = 2; p <= n; p++)
if (prime[p])
printf("%d ", p);
}
推荐阅读
- flutter - 提供者状态在热重载时丢失 - 颤动
- django - 使用代理模型作为信号发送者
- ruby-on-rails - 如何省略没有孩子的父母
- angular - 如何使用 switchMap 提取查询参数
- reactjs - React - 如何比较基于 API 的 prev 和 current state
- java - 如何将 .zip 库添加到 Eclipse
- visual-studio - 运行留言簿示例时,纱线开发错误命令失败,退出代码为 1
- pytorch - 在 PyTorch 的自定义后端中获取子组排名信息
- python - 从 Python 中的 MultiLineString GeoJSON 中提取坐标(纬度,经度)
- javascript - 根据其值更改 R 闪亮数据表的单元格颜色