0

I don't need any of this, it's for fun

I implemented realloc on linux before using map and mremap. I ran dtruss on the below code and I see two write calls, nothing in between. Using bash and time b.c is significantly slower than a.c which leaves me to believe realloc doesn't use a memcpy (and likely changes virtual pages).

If I wanted to implement my own C library or write a realloc in assembly how would I implement it to get as good performance as a.c?

% cat a.c b.c

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main() {
    write(1, "Hel", 3);
    void*p1=malloc(1024*1024*512);
    memset(p1, '1', 1024*1024*512);
    malloc(4096);
    void*p =realloc(p1, 1024*1024*1024);
    memset(p+1024*1024*512, '0', 1024*1024*512);
    write(1, "lo\n", 3);
}

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main() {
    write(1, "Hel", 3);
    void*p1=malloc(1024*1024*512);
    memset(p1, '1', 1024*1024*512);
    void*p =malloc(1024*1024*1024);
    memcpy(p, p1, 1024*1024*512);
    memset(p+1024*1024*512, '0', 1024*1024*512);
    write(1, "lo\n", 3);
}
Stan
  • 161
  • 8
  • https://stackoverflow.com/questions/19542178/where-can-i-find-the-source-of-libsystem-c-dylib – Some programmer dude Dec 03 '22 at 01:26
  • 1
    On my system [linux/x86], I get the opposite result. a: `0.043u 0.223s 0:00.26 100.0% 0+0k 0+0io 0pf+0w` b: `0.000u 0.000s 0:00.00 0.0% 0+0k 0+0io 0pf+0w` There's nothing in `malloc` et. al. that lends itself to hand written assembly. Note: `a` leaks memory with `malloc(4096)`. Using `time` from a shell probably isn't accurate enough. And, because of the `write` calls, the programs will spend the bulk of their time on I/O rather than what you want to measure. – Craig Estey Dec 03 '22 at 02:35
  • @CraigEstey: I'd hope that Linux uses `mremap(MREMAP_MAYMOVE)`. That system call is Linux-specific. IDK if MacOS has one that's equivalent, or if it might just try to `mmap()` with a hint address contiguous with the end of the first allocation to try to grow it. Or not even attempting that. Single-stepping into it would be the way to go, or use a profiler to find where it spends time; if it runs a copy loop, that would find it. – Peter Cordes Dec 03 '22 at 07:41
  • @CraigEstey the leak was intentional, so malloc couldn't extend the memory block. The memcpy is what eats up the time. – Stan Dec 03 '22 at 07:55

0 Answers0