3

I need a thread-unsafe, lockless malloc to use it in a single threaded application. I expect to gain a little performance boost because of this. I need it on win and linux, and it must guaranteed to be single-threaded. Any ideas?

Iurii
  • 125
  • 2
  • 4
  • 8
    What makes you think `malloc()` is thread-safe? – Frédéric Hamidi Jul 25 '11 at 13:13
  • 9
    @Frédéric: Perhaps the fact that every single thread specification of modern relevance *requires* it to be? Stop spreading ignorance... – R.. GitHub STOP HELPING ICE Jul 25 '11 at 13:15
  • 4
    @lurii: Do you know what they say about premature optimization? – R.. GitHub STOP HELPING ICE Jul 25 '11 at 13:15
  • 2
    @R.., `malloc()`'s "thread safety" is implementation-dependent AFAICT. Maybe you have other information? :) – Frédéric Hamidi Jul 25 '11 at 13:17
  • it must guaranteed to be unsafe lol – unkulunkulu Jul 25 '11 at 13:18
  • 1
    @Frédéric: POSIX threads (http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_09_01), C1x (http://port70.net/~nsz/c/c1x/n1548.html - the very fact that it includes threads and does not make any allowance for `malloc` to have UB when used with threads means it must be thread-safe), Windows (look it up yourself; I'm not a Windows person), Solaris threads (same...) – R.. GitHub STOP HELPING ICE Jul 25 '11 at 13:24
  • 3
    @R: http://stackoverflow.com/q/855763/498253. Its implementation defined and depends on the compiler settings. It is often the case that by default malloc is threadsafe, but on some implementations you can change this with compiler flags. The question specifically mentions cross platform usage. You are wrong when you say malloc is required to be threadsafe - on my modern compiler I can turn this feature off. – Tom Jul 25 '11 at 13:31
  • You possibly gain more performance when you instead make your application multithreaded. – Sebastian Mach Jul 25 '11 at 14:03

5 Answers5

2

Have you actually profiled your code and shown that it's spending a significant portion of its time in malloc? I would say instead of a replacement malloc, first consider an alternate algorithm that doesn't do as much dynamic allocation. If that's not an option I would consider a memory pool approach (they can be very fast with fixed-size blocks).

Mark B
  • 91,641
  • 10
  • 102
  • 179
  • It's been a while, but still. Yes, I profiled that code. Maximum performance on two threads (just about x 1,95) I achieved when replaced all memory allocations by pooling. But in many cases I wouldn't even start such a war. I'd prefer to have per-thread allocator that doesn't hit my performance when going to multi-threading. – Iurii Sep 29 '15 at 12:07
2

To answer the question, some implementations have compiler options to remove the thread safety from malloc. This answer: Is malloc thread-safe? suggests that NO_THREADS can be defined to remove the thread-safety from malloc, but I have not tested this.

You should listen to the other posts, however, it is unlikely to be the best place to start your optimisiations.

Community
  • 1
  • 1
Tom
  • 5,019
  • 1
  • 26
  • 43
1

One approach is to allocate a pool of memory yourself and then allocate locally from within that (see memory pool). As the comments point out, malloc is already pretty clever, so benchmarking is important.

Jeff Foster
  • 40,078
  • 10
  • 78
  • 103
  • 1
    I'd be careful with statements like "the best approach". Modern implementations of `malloc()` already do all sorts of internal magic and they don't actually make a system call every time, so you really have to benchmark and compare. – Kerrek SB Jul 25 '11 at 13:18
  • Good point. Should have been "has sometimes in the past worked for me, but your mileage may vary" :) I've altered the description accordingly. – Jeff Foster Jul 25 '11 at 13:21
  • 1
    Cheers :-) Also, you might want to look at some existing mallocs and allocators. I think I've had some pretty good experience with Google's tcmalloc once, and nedalloc claims to be super fast. Boost's pool allocator on the other hand hasn't been helpful to me. It's very situational! – Kerrek SB Jul 25 '11 at 13:25
  • Yes, my decision was memory pool, but question still there. I don't want to use memory pool everywhere - its too much work. – Iurii Oct 03 '15 at 07:06
1

The overhead from a thread-safe malloc (if existant) in a single-threaded application is most likely insignificant to the time required to allocate the memory from the OS. Please first profile the bottlenecks in your program and then start optimizing.

orlp
  • 98,226
  • 29
  • 187
  • 285
0

Have you profiled your code and seen that malloc() really is the place where the time is spent? I just want to check to make sure, but if malloc() is the bottleneck there are some things that can be done about it.

First I don't think that thread locking is the issue.

The main problem with malloc() especially in long running applications doing lots of allocations and frees is fragmentation of memory. malloc()'s basic task is to look at the available memory blocks and search for one that is large enough to fulfill the requested size. When such a block is found, as much as required is used and the rest is noted as a free block. After lots of allocations, this can lead to memory fragmentation where the free memory is split into a large number of small blocks. Searching for a free, large enough block among these is a common reason for performance problems.

There are a sine strategies that can be implemented to remedy this:

  • Always allocated a memory block that is a power of 2 in size, rounding up to the nearest boundary. This prevents fragmentation.
  • Make your own allocation mechanism for commonly used block sizes in your application, by allocating bunches of for say 100 structs at the same time. Wikipedia has an article on Memory pools.
Anders Abel
  • 64,109
  • 15
  • 143
  • 213