为什么此OpenMP代码在Linux上却不能在Windows上运行?

时间:2019-05-16 19:43:23

标签: c arrays openmp variable-length-array

编辑:解决了! 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而不是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;
}

2 个答案:

答案 0 :(得分:4)

本地buffer变量需要1920 * 1080 * 3(6,220,800)字节的空间。这大于Windows应用程序中的默认堆栈大小。

如果使用的是Microsoft工具,则可以使用/STACK链接器选项来指定更大的堆栈。

借助GCC工具链,您可以使用--stack,8000000选项设置更大的堆栈大小。

或者您可以使用buffermalloc动态分配空间。

第三种选择是使用editbin工具指定可执行文件生成后的大小。

答案 1 :(得分:2)

fprintf(image, "%d %d %d\n", buffer[w][h][0], buffer[w][h][1], buffer[w][h][2]);

您正在访问bufferbuffer的最高有效索引是w - 1h - 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]);