3

I'm developing a multi-threaded application in C. I'm currently playing with 40 threads and each uses an array of around 2Mb.

I'm currently allocating this array dynamically, so I do:

char *data = malloc(2097152 * sizeof(char));

These threads are serving requests, so this array is constantly allocated and free'd, each time a new request comes in.

All is working fine, but I'm using valgrind's massif tool and it shows me that I have at times an 80Mb heap. So I'm kind of wondering, will I have heap fragmentation problems? I also allocate smaller chunks of memory on other places of my code.

Also, would I benefit from having an static array? I'm looking of ways to improve my performance and I wonder if this would help. However, I'm afraid of doing that and ending up with a stack overflow. 80Mb in the stack seems too large...

Any advice? I really don't know what size of heap/stack is too big.

trincot
  • 317,000
  • 35
  • 244
  • 286
Camilla
  • 47
  • 3
  • 4
    How can you end-up with a 80 MB stack? Anyway yes, you'll have some fragmentation but it should be easy to setup a _pool_ where arrays will be reused... – Adriano Repetti May 14 '15 at 14:16
  • Why are you using dynamic memory when you have a fixed size? that is likely slowing you up ALOT – that-ru551an-guy May 14 '15 at 14:16
  • Using stack I think is not possible. BTW, if you can define a maximum required array, each task can malloc its own array and use always the same memory. This willa void fragmentation, because of you have not to free memory. – LPs May 14 '15 at 14:20
  • You are actually in the limit for using the stack, since each thread has it's own stack of `2M` on linux AFAIK, so you can't grow your arrays more than that, read [here](http://man7.org/linux/man-pages/man3/pthread_create.3.html). – Iharob Al Asimi May 14 '15 at 14:22
  • @that-ru551an-guy , Try declaring `char data[2097152]` on the stack and you'll be surprised. It won't ( mostly ) compile. – Spikatrix May 14 '15 at 14:24
  • 5
    Why is a heap of 80MB a problem when 40 threads using 2MB each ciphers out to 80MB? – Michael Burr May 14 '15 at 14:24
  • 3
    Just FYI, `sizeof(char)` is ***always*** and ***everywhere*** 1 ... see [Are there machines, where sizeof(char) != 1?](http://stackoverflow.com/questions/2215445/are-there-machines-where-sizeofchar-1) – Sinan Ünür May 14 '15 at 14:27
  • Using the stack is almost trivial. Just set a large stack for each thread using `pthread_attr_setstack()`. (http://man7.org/linux/man-pages/man3/pthread_attr_setstack.3.html) But you'd still need to get that stack memory from _somewhere_, either from `mmap()` or the heap. So unless each thread would continually `malloc()/free()` memory over and over if it didn't have a large stack to use, it won't matter. – Andrew Henle May 14 '15 at 14:32
  • If you don't mind the executable image being much larger than it currently is, then allocate them all in the data-section (by declaring them `staitc` or global or both). – barak manos May 14 '15 at 14:46
  • 2
    *so this array is constantly allocated and free'd, each time a new request comes in* why? Why can't the threads work with same memory each time without malloc'ing again? The main problem with stack is that you don't know if allocation failed and also depends if you use more stack storage other than this. So probably dangerous. Also most systems have a default stack size as 8MB (can change of course). So malloc'ing is probably the way to go. – P.P May 14 '15 at 15:08
  • Use static array if possible. However if you want to allocate memory dynamically use "int posix_memalign (void **memptr, size_t alignment, size_t size)" and align it to your pagesize. – Alam May 14 '15 at 17:17

1 Answers1

1

You seem to be heading in this direction anyway, but there are some design patterns that you could be using to assist you in this.

firstly memory pooling http://www.codeproject.com/Articles/27487/Why-to-use-memory-pool-and-how-to-implement-it This can be used to remove the overhead of allocating and de-allocating the memory.

second I am going to assume that you are creating threads as well for the sake of completeness

so thread pooling, if you have a pool of threads that access a pool of memory you should be sorted. http://en.wikipedia.org/wiki/Thread_pool_pattern

Hopefully this gives you some help on ideas on how you can go solve your issue.

JamesD
  • 2,466
  • 24
  • 40