下面是一个工作非常好的循环:
#include <inttypes.h>
#include <iostream>
int main() {
for (int32_t i = -2; i < INT32_MAX-2; i++) {
std::cout << i << std::endl;
}
}添加omp parallel for子句似乎通过引入int溢出来破坏代码。
#include <inttypes.h>
#include <iostream>
int main() {
#pragma omp parallel for
for (int32_t i = -2; i < INT32_MAX; i++) {
std::cout << i << std::endl;
}
}对于clang-10和gcc-10,程序都没有输出.另一方面,clang-12似乎处理得很好。
clang-10至少会产生一些警告:
> clang++-10 int_div.cpp -Wall -fopenmp
int_div.cpp:133:3: warning: overflow in expression; result is -2147483647 with type 'int' [-Winteger-overflow]
for (int i = -2; i < INT32_MAX; i++) {
^
int_div.cpp:133:3: warning: overflow in expression; result is 2147483646 with type 'int' [-Winteger-overflow]
int_div.cpp:133:3: warning: overflow in expression; result is -2147483647 with type 'int' [-Winteger-overflow]
int_div.cpp:133:3: warning: overflow in expression; result is -2147483647 with type 'int' [-Winteger-overflow]
int_div.cpp:133:3: warning: overflow in expression; result is -2147483647 with type 'int' [-Winteger-overflow]这是一个合法的,定义明确的openmp标准行为还是一个实现缺陷?
发布于 2022-01-07 17:43:24
它不是编译器中的bug,而是OpenMP中未指定的行为。请参阅2.9.1标准环形式
如果var为整数类型,则该类型为var的类型。 ..。 如果计算迭代计数所需的任何中间结果不能用上面确定的类型表示,则行为未指定。
类似的措辞可以在241换建筑的Microsoft站点上找到。
此计算是在积分提升后,使用var类型的值进行的。特别是,如果b- lb + incr的值不能用该类型表示,则结果是不确定的。
因此,计算是在int中进行的,导致整数溢出,从而导致UB。
发布于 2022-01-06 04:12:54
#pragma omp parallel for将导致循环计数的omp_get_num_threads()执行流,如下所示:
for (int32_t i = -2; i < INT32_MAX; i += omp_get_num_threads())
std::cout << i << std::endl;
for (int32_t i = -1; i < INT32_MAX; i += omp_get_num_threads())
std::cout << i << std::endl;
// ...
for (int32_t i = -2 + omp_get_thread_num() - 1; i < INT32_MAX; i += omp_get_num_threads())
std::cout << i << std::endl;第二个线程和其他线程将导致有符号整数溢出。
发布于 2022-01-06 05:30:12
OpenMP循环需要在开始循环之前计算迭代次数,因此循环变量的类型必须是可以表示的。除此之外,OMP标准允许有符号整数类型和无符号整数类型,不受任何限制。
https://stackoverflow.com/questions/70602278
复制相似问题