2

Edit: solved! Windows limits the stack size to where my buffer does not fit; linux does not (additionaly I was accessing memory outside of my array... oops). Using gcc, you can set the stack size like so: gcc -Wl --stack,N [your other flags n stuff] where N is the size of the stack in bytes. Final working compile command: gcc -Wl --stack,8000000 -fopenmp openmp.c -o openmp

An interesting sidenote is that the rand() function seems to produce smaller patterns than in Linux, because I can see patterns (tiling) in the generated noise on Windows, but not on Linux. As always, if you need it to be absolutely random, use a cryptographically secure rand function.

Pre edit:

This piece of code is supposed to make a screenbuffer of randomnoise, then write that to a file. It works on linux (ubuntu 19) but not on windows (8.1).

The error message:

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;
}
AnnoyinC
  • 426
  • 4
  • 17

2 Answers2

4

The local buffer variable wants 1920 * 1080 * 3 (6,220,800) bytes of space. This is more than the default stack size on a Windows application.

If you were using the Microsoft tools, you could use the /STACK linker option to specify a larger stack.

With the GCC toolchain, you can use the --stack,8000000 option to set a larger stack size.

Or you can dynamically allocate space for buffer using malloc.

A third alternative is to use the editbin tool to specify the size after the executable is built.

1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56
  • This seems the most likely then. How do I use /STACK in a C file? Everyone is talking about "properties > Configuration Properties -> Linker -> System -> Stack Reserve Size" however, where is this???? I'm using Sublime Text editor – AnnoyinC May 16 '19 at 20:18
  • @AnnoyinC That is in the Visual Studio IDE. If you're not using that, then you can put it on the command line, either as part of the `link` command or after a `/link` option passed to `CL` (the compiler). – 1201ProgramAlarm May 16 '19 at 20:19
  • 1
    I'm using gcc. I found that "gcc -Wl,--stack,8000000" worked. This sets the stack size to 8mb, which easily accomodates my 6.2mb array. Thank you for pointing me in this direction, my program now compiles and works! – AnnoyinC May 16 '19 at 20:24
2

In

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

you are accessing buffer out of bounds. The highest valid indices for buffer are w - 1 and 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]);
Swordfish
  • 12,971
  • 3
  • 21
  • 43
  • Oh, of course. And the reason it worked on linux is because it compiled to something slightly different that did not raise an error. And the reason I didn't see the random noise from the random data at the wrong memory location is because the entire image was noise anyway. Thanks! – AnnoyinC May 16 '19 at 20:07
  • 2: I edited the line to what you suggested, but the same error pops up. When I debug using vs2019, then press continue, it gives me an access violation writing location error, but I'm not sure what it is this time. – AnnoyinC May 16 '19 at 20:11
  • @AnnoyinC Sorry, but that's all I've seen on the first glance. – Swordfish May 16 '19 at 20:16