为什么此 OpenMP 代码适用于 Linux,但不适用于 Windows?
Why does this OpenMP code work on Linux, but not Windows?
编辑:已解决! Windows 将堆栈大小限制在我的缓冲区不适合的地方; linux 没有(另外我正在访问数组之外的内存......哎呀)。使用 gcc,您可以像这样设置堆栈大小: gcc -Wl --stack,N [your other flags n stuff]
其中 N 是以字节为单位的堆栈大小。最终工作编译命令:gcc -Wl --stack,8000000 -fopenmp openmp.c -o openmp
一个有趣的旁注是 rand() 函数似乎产生比 Linux 更小的模式,因为我可以在 Windows 上看到生成的噪声中的模式(平铺),但在 Windows 上看不到Linux。与往常一样,如果您需要它是绝对随机的,请使用加密安全 rand 函数。
编辑前:
这段代码应该制作随机噪声的屏幕缓冲区,然后将其写入文件。它适用于 linux (ubuntu 19) 但不适用于 windows (8.1).
错误信息:
Unhandled exception at 0x0000000000413C46 in openmp.exe:
0xC00000FD: Stack overflow (parameters: 0x0000000000000001, 0x0000000000043D50).
0000000000413C46 or qword ptr [rcx],0
// gcc -fopenmp openmp.c -o openmp
// ./openmp
#include <stdlib.h>
#include <stdio.h>
#include <omp.h>
#include <stdint.h>
int main(int argc, char **argv)
{
int w = 1920;
int h = 1080;
int thread_id, nloops;
unsigned char buffer[w][h][3]; // 1920 x 1080 pixels, 3 channels
printf("Did setup\n");
#pragma omp parallel private(thread_id, nloops)
{
nloops = 0;
thread_id = omp_get_thread_num();
printf("Thread %d started\n", thread_id);
#pragma omp for
for (int x = 0; x < w; x++){
for (int y = 0; y < h; y++){
nloops++;
unsigned char r = rand();
unsigned char g = rand();
unsigned char b = rand();
buffer[x][y][0] = r;
buffer[x][y][1] = g;
buffer[x][y][2] = b;
}
}
printf("Thread %d performed %d iterations of the loop.\n", thread_id, nloops);
}
FILE* image = fopen("render.ppm","w");
fprintf(image, "P3\n%d %d\n%d\n", w, h, 255);
for (int x = 0; x < w; x++){
for (int y = 0; y < h-1; y++){
fprintf(image, "%d %d %d ", buffer[x][y][0], buffer[x][y][1], buffer[x][y][2]);
}
fprintf(image, "%d %d %d\n", buffer[w][h][0], buffer[w][h][1], buffer[w][h][2]);
}
printf("%fmb\n", ((float)sizeof(buffer))/1000000);
return 0;
}
在
fprintf(image, "%d %d %d\n", buffer[w][h][0], buffer[w][h][1], buffer[w][h][2]);
您正在 buffer
越界访问。 buffer
的最高有效索引是 w - 1
和 h - 1
:
fprintf(image, "%d %d %d\n", buffer[w - 1][h - 1][0], buffer[w - 1][h - 1][1], buffer[w - 1][h - 1][2]);
局部buffer
变量需要space 的1920 * 1080 * 3 (6,220,800) 个字节。这超过了 Windows 应用程序的默认堆栈大小。
如果您使用的是 Microsoft 工具,则可以使用 /STACK
链接器选项来指定更大的堆栈。
使用 GCC 工具链,您可以使用 --stack,8000000
选项来设置更大的堆栈大小。
或者您可以使用 malloc
为 buffer
动态分配 space。
第三种选择是使用 editbin
工具在生成可执行文件后指定大小。
编辑:已解决! Windows 将堆栈大小限制在我的缓冲区不适合的地方; linux 没有(另外我正在访问数组之外的内存......哎呀)。使用 gcc,您可以像这样设置堆栈大小: gcc -Wl --stack,N [your other flags n stuff]
其中 N 是以字节为单位的堆栈大小。最终工作编译命令:gcc -Wl --stack,8000000 -fopenmp openmp.c -o openmp
一个有趣的旁注是 rand() 函数似乎产生比 Linux 更小的模式,因为我可以在 Windows 上看到生成的噪声中的模式(平铺),但在 Windows 上看不到Linux。与往常一样,如果您需要它是绝对随机的,请使用加密安全 rand 函数。
编辑前:
这段代码应该制作随机噪声的屏幕缓冲区,然后将其写入文件。它适用于 linux (ubuntu 19) 但不适用于 windows (8.1).
错误信息:
Unhandled exception at 0x0000000000413C46 in openmp.exe:
0xC00000FD: Stack overflow (parameters: 0x0000000000000001, 0x0000000000043D50).
0000000000413C46 or qword ptr [rcx],0
// gcc -fopenmp openmp.c -o openmp // ./openmp
#include <stdlib.h>
#include <stdio.h>
#include <omp.h>
#include <stdint.h>
int main(int argc, char **argv)
{
int w = 1920;
int h = 1080;
int thread_id, nloops;
unsigned char buffer[w][h][3]; // 1920 x 1080 pixels, 3 channels
printf("Did setup\n");
#pragma omp parallel private(thread_id, nloops)
{
nloops = 0;
thread_id = omp_get_thread_num();
printf("Thread %d started\n", thread_id);
#pragma omp for
for (int x = 0; x < w; x++){
for (int y = 0; y < h; y++){
nloops++;
unsigned char r = rand();
unsigned char g = rand();
unsigned char b = rand();
buffer[x][y][0] = r;
buffer[x][y][1] = g;
buffer[x][y][2] = b;
}
}
printf("Thread %d performed %d iterations of the loop.\n", thread_id, nloops);
}
FILE* image = fopen("render.ppm","w");
fprintf(image, "P3\n%d %d\n%d\n", w, h, 255);
for (int x = 0; x < w; x++){
for (int y = 0; y < h-1; y++){
fprintf(image, "%d %d %d ", buffer[x][y][0], buffer[x][y][1], buffer[x][y][2]);
}
fprintf(image, "%d %d %d\n", buffer[w][h][0], buffer[w][h][1], buffer[w][h][2]);
}
printf("%fmb\n", ((float)sizeof(buffer))/1000000);
return 0;
}
在
fprintf(image, "%d %d %d\n", buffer[w][h][0], buffer[w][h][1], buffer[w][h][2]);
您正在 buffer
越界访问。 buffer
的最高有效索引是 w - 1
和 h - 1
:
fprintf(image, "%d %d %d\n", buffer[w - 1][h - 1][0], buffer[w - 1][h - 1][1], buffer[w - 1][h - 1][2]);
局部buffer
变量需要space 的1920 * 1080 * 3 (6,220,800) 个字节。这超过了 Windows 应用程序的默认堆栈大小。
如果您使用的是 Microsoft 工具,则可以使用 /STACK
链接器选项来指定更大的堆栈。
使用 GCC 工具链,您可以使用 --stack,8000000
选项来设置更大的堆栈大小。
或者您可以使用 malloc
为 buffer
动态分配 space。
第三种选择是使用 editbin
工具在生成可执行文件后指定大小。