r/C_Programming 6h ago

Etc I actually had a laugh yesterday

27 Upvotes

I was coding up some piece that is supposed to rapidly parse millions of text logfiles. A file gets read into a buffer, and then the parser goes to work, peppering the buffer with zeros and building linked lists with pointers to the relevant bits, using two passes across the whole buffer. This was easy but I was unsure if I should use a different approach for efficiency. So I wrote a minimal test and measured the time for one logfile and spit out timestamp deltas for filling and chopping up the buffer, respectively. The results in milliseconds:

25.4
4.7

Not great for a 30kB file but the important message is: The parser isn't what needs to be optimized, for now anyway. Maybe it's the progressive realloc()ing of the buffer as it grows (RAM isn't free any more in AI times you know). But then I noticed that the program was still running under valgrind. After I took that out, I got:

0.0
0.0

I had to increase the decimal digits to see the microseconds. I found that hilarious. My colleague wondered what was wrong with me. I started C on a 2MHz/32kB machine. 25 ms read time for 30kB is still "pretty fast" in my book.

BTW, the speed of the incremental chunk-wise fread()/realloc() cycle is surprisingly immune against chunk size. Between 100 bytes and 10k it's not even a factor of 2.

[EDIT] The file size is not known beforehand. The data will be fed into this system by repeated calls to a user-supplied callback function. And realloc() seems to be dirt cheap if you don't let production code run under valgrind ;-)


r/C_Programming 3h ago

Question Question about alignment in a custom memcpy implementation

2 Upvotes

I'm implementing my own memcpy as an exercise.

My current approach is:

  1. Copy bytes until dst reaches a 4-byte-aligned address.
  2. Copy 4 bytes at a time using uint32_t.
  3. Copy the remaining bytes one by one.

I understand that this optimization works nicely when src and dst have the same alignment offset, e.g.:

src = 0x1001
dst = 0x2001

src % 4 == dst % 4

What I don't understand is why I can't simply perform an unaligned 32-bit load/store when the offsets are different.

For example:

src = 0x1001
dst = 0x2002

Why can't I simply do:

uint32_t x = *(uint32_t *)src;
*(uint32_t *)dst = x;

This seems like it should copy exactly the desired 4 bytes.

I understand that unaligned accesses may be slower, fault on some architectures, or have restrictions for MMIO. But assuming I'm on an architecture where unaligned 32-bit accesses are supported, is there actually a correctness problem?

I'm trying to understand the fundamental reason rather than just memorize the "same alignment" rule.

Thanks!