6

While looking at the libc++ implementation of std::basic_string, I came across this in line 1374 (at the time of writing):

enum {__alignment = 16};

This value is used in subsequent alignment calculations, string size requests being rounded up to multiples of this number.

I can accept that some rounding is going on to avoid memory fragmentation or whatever, but...

I wonder if there is any specific rationale behind using a hardcoded 16 as the number here, or if it's just used as a "nice 'round' number".

For a 64-bit machine, 16 amounts to alignof( std::max_align_t ), and that makes some sort of sense. But the exact same value for __alignment is used for 32-bit architectures as well, so...?

TylerH
  • 20,799
  • 66
  • 75
  • 101
DevSolar
  • 67,862
  • 21
  • 134
  • 209
  • 2
    FWIW, I've tried `svn blame` on the repo to perhaps find something in the commit logs, but it's been in there since @103490 "libcxx initial import"... – DevSolar May 21 '18 at 16:33
  • 1
    In libc++ what's the granularity of a heap allocation? Could it be as high as 16 bytes? – davidbak May 21 '18 at 16:39
  • @davidbak: We-ell... wouldn't *that* be up to the allocator? – DevSolar May 21 '18 at 16:41
  • There must be a built-in allocator though. Or at least a canonical/default allocator used by ... gcc? Whoever was using libc++ back then @103490. 16 bytes seems high to me, but you never know, that's why I'm asking. (Specifically: What was the heap granularity _then_ as most often these derived "dependencies" never get updated later ...) – davidbak May 21 '18 at 16:43
  • If I had to guess, this could this be so that std::string is simd-friendly, allowing for faster algorithms on it. –  May 21 '18 at 16:48
  • Or even just bus-friendly. Don't know when @103490 was (not sufficiently motivated to look, my bad, sorry) but is it possible that even for early 32-bit implementations there were popular machines that had a 16-byte data bus width? IDK, SPARC maybe? – davidbak May 21 '18 at 16:51
  • @103490 was the *import* of the (obviously already existing) libc++ sources into the llvm repo... no idea if the previous repo is even persisted anywhere. :-\ -- Couldn't find a hardcoded 16 in `` or elsewhere (other than in ``, which is obviously not relevant). – DevSolar May 21 '18 at 16:55
  • Sometimes I would really give something for source comments... – DevSolar May 21 '18 at 16:56
  • I get that it was an import, I just don't even know how far back in time that was, much less when 16 was originally chosen. BTW, w.r.t. your wistful wish for source comments: Yes, but - the original author would have had to agree with you _then_ that that particular design choice was worth commenting ... and you know, chances are, he wouldn't have ... because ... "16" was obvious to him and everyone around him, most likely. – davidbak May 21 '18 at 16:58
  • @davidbak: Revision 103490 was logged on 2010-05-11. And yes, I'm somewhat verbose with comments on architectural decisions. I'll point to this question when co-workers next give me flak for that. ;-) – DevSolar May 21 '18 at 17:00
  • It might be for SSO, see https://stackoverflow.com/q/10315041/5987 and https://stackoverflow.com/q/21694302/5987. – Mark Ransom May 21 '18 at 20:56
  • @MarkRansom: Inhowfar? The `__alignment` is only ever used for *dynamic* allocations. Capacity for SSO is 23 char's on 64bit and 11 char's on 32bit (pointer to data, counter for length, counter for capacity). – DevSolar May 21 '18 at 21:06

1 Answers1

6

When I first designed <string>, libc++ wasn't yet destined to be open-source. I was writing for Apple's platforms only. And Apple's malloc always allocates at least 16 bytes, and in multiples of 16 bytes, no matter how much you ask for (at least this was true in 2007, I haven't checked recently).

So if the most commonly used allocator is going to hand you 16 bytes, you might as well use them in your capacity.

At one time, a few years earlier, I tried to change the allocator API so that it could ask the allocator how much memory it actually handed out for any particular request. But that attempt failed. So the next best thing was taking advantage of a-priori knowledge of the most common allocator the code was going to deal with.

Howard Hinnant
  • 206,506
  • 52
  • 449
  • 577
  • Thank you for that information! Wouldn't `alignof( max_align_t )` be basically the number you are looking for -- the alignment for standard memory allocation? – DevSolar May 24 '18 at 06:56
  • 2
    Yes. I didn't use it because it wasn't in my toolbox at the time. – Howard Hinnant May 24 '18 at 14:12