当我尝试减少一个大堆阵列以减少开放量时,它会段故障:
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
double *test = NULL;
size_t size = (size_t)1024 * 1024 * 16; // large enough to overflow openmp threads' stack
test = malloc(size * sizeof(double));
#pragma omp parallel reduction(+ : test[0 : size]) num_threads(2)
{
test[0] = 0;
#pragma omp critical
{
printf("frame address: %p\n", __builtin_frame_address(0));
printf("test: %p\n", test);
}
}
free(test);
printf("Allocated %zu doubles\n\n", size);
}
请注意,请注意double *test
是在堆上分配的,因此不是this和this.的重复。 th这个示例可与小尺寸数组一起使用,但段故障具有较大的数组。数组分配在堆上,系统内存就足够了。 SIMIMAR问题但是,即使在堆上分配了数组,段错误仍然会发生。
在其他社区中也有同样的问题:
https://forums.oracle.com/ords/apexds/post/segentation-fault-with-with-large-arrays-andares-and-openmp-1728 我认为应该有一个真正的解决方案,所以我在GCC的Bugzilla上发出错误:https://gcc.gnu.org/bugzilla/show_bug.cgi?id =118909
thanks to jakub jelinek,此错误的原因是,大多数编译器都在堆栈上分配私有数据,这对性能有益。如果您确实需要大型私有数据,则可以通过设置
OMP_STACKSIZE指定它应在堆上分配。
因此,解决方案是添加allocate(test)
以在堆上使私有化test
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
double *test = NULL;
size_t size = (size_t)1024 * 1024 * 16;
test = malloc(size * sizeof(double));
#pragma omp parallel reduction(+ : test[0 : size]) num_threads(2) allocate(test)
{
test[0] = 0;
#pragma omp critical
{
printf("frame address: %p\n", __builtin_frame_address(0));
printf("test: %p\n", test);
}
}
free(test);
printf("Allocated %zu doubles\n\n", size);
}