有没有办法从有序条款中取消?
Is there a way to cancel from inside ordered clause?
我正在开发一个程序,使用多线程计算一定数量的素数。现在我 运行 遇到了在所述素数后退出线程的问题。
我试过 #pragma omp cancel for
,但我不能在有序子句中使用它。还有其他方法可以 "break" 循环吗?
void get_primes(prime_type start, prime_type end) {
#pragma omp parallel for ordered schedule(dynamic) shared(prime_counter)
for (candidate = start; candidate <= end; candidate += 2) {
if (is_prime(candidate)) {
#pragma omp ordered
{
primes[prime_counter] = candidate;
prime_counter++;
if (prime_counter >= max_primes) {
#pragma omp cancel for
}
#pragma omp cancellation point for
}
}
}
}
我想在找到所需数量的素数后立即"break"循环,如果我没记错的话,必须在有序子句中完成。
没有。无法取消有序循环。
A loop construct that is canceled must not have an ordered clause.
(参见 OpenMP 标准的 2.14.1)
模拟取消的解决方法之一是在循环的开头添加一个跳过,例如
#pragma omp parallel for ordered schedule(dynamic) shared(prime_counter)
for (candidate = start; candidate <= end; candidate += 2) {
if (prime_counter >= max_primes) {
continue;
}
if (is_prime(candidate)) {
但是,这还不是对 prime_counter
的线程安全访问。为了避免竞争条件,你必须按照以下方式做一些事情:
int local_prime_counter;
#pragma omp atomic read
local_prime_counter = prime_counter;
if (local_prime_counter >= max_primes)
...
#pragma omp atomic update
prime_counter++;
P.S。我不是 100% 确定它是否符合条件 ordered
构造的标准。
我正在开发一个程序,使用多线程计算一定数量的素数。现在我 运行 遇到了在所述素数后退出线程的问题。
我试过 #pragma omp cancel for
,但我不能在有序子句中使用它。还有其他方法可以 "break" 循环吗?
void get_primes(prime_type start, prime_type end) {
#pragma omp parallel for ordered schedule(dynamic) shared(prime_counter)
for (candidate = start; candidate <= end; candidate += 2) {
if (is_prime(candidate)) {
#pragma omp ordered
{
primes[prime_counter] = candidate;
prime_counter++;
if (prime_counter >= max_primes) {
#pragma omp cancel for
}
#pragma omp cancellation point for
}
}
}
}
我想在找到所需数量的素数后立即"break"循环,如果我没记错的话,必须在有序子句中完成。
没有。无法取消有序循环。
A loop construct that is canceled must not have an ordered clause.
(参见 OpenMP 标准的 2.14.1)
模拟取消的解决方法之一是在循环的开头添加一个跳过,例如
#pragma omp parallel for ordered schedule(dynamic) shared(prime_counter)
for (candidate = start; candidate <= end; candidate += 2) {
if (prime_counter >= max_primes) {
continue;
}
if (is_prime(candidate)) {
但是,这还不是对 prime_counter
的线程安全访问。为了避免竞争条件,你必须按照以下方式做一些事情:
int local_prime_counter;
#pragma omp atomic read
local_prime_counter = prime_counter;
if (local_prime_counter >= max_primes)
...
#pragma omp atomic update
prime_counter++;
P.S。我不是 100% 确定它是否符合条件 ordered
构造的标准。