4

I have some code that interprets multibyte width integers from an array of bytes at an arbitrary address.

std::vector<uint8> m_data; // filled with data
uint32 pos = 13;           // position that might not be aligned well for 8 byte integers
...

uint64 * ptr = reinterpret_cast<uint64*>(m_data.data() + pos);
*ptr = swap64(*ptr);  // (swaps endianness)

Would alignment be an issue for this code? And if it is, is it a severe issue, or one that can safely be ignored because the penalty is trivial?

Alan Birtles
  • 32,622
  • 4
  • 31
  • 60
Anne Quinn
  • 12,609
  • 8
  • 54
  • 101
  • 7
    This [violates strict aliasing](https://stackoverflow.com/a/51228315/1708801) and [alignment does matter](http://pzemtsov.github.io/2016/11/06/bug-story-alignment-on-x86.html) – Shafik Yaghmour Jul 30 '18 at 06:25
  • 2
    Why not measure and benchmark? Do that a few million times and compare with aligned access done a few million times. – Some programmer dude Jul 30 '18 at 06:25
  • 1
    If `pos` is always divisible by 8, (or more precisely data+pos is divisible by 8), then there is no penalty for mis-alignment. But I'm with SPD. Go measure it compare to the cost of a memcpy into a temp variable. Also, on some older platforms (e.g. sun sparc), accessing a variable on a misaligned address would crash. But I believe most platforms chip+OS will do the appropriate fixup when this happens. What the cost of that fixup is - unknown. Go measure it. – selbie Jul 30 '18 at 06:33
  • Also note that alignment is very much of importance when performing atomic operations and other types of intrinsics. Those can bite you hard. – Athos vk Jul 30 '18 at 07:28

2 Answers2

2

Use memcpy instead:

uint64_t x;
memcpy(&x, m_data.data()+pos, sizeof(uint64_t));
x = swap(x);
memcpy(m_data.data()+pos, &x, sizeof(uint64_t));

It has two benefits:

  • you avoid strict aliasing violation (caused by reading uint8_t buffer as uint64_t)
  • you don't have to worry about misalignment at all (you do need to care about misalignment, because even on x86, it can crash if the compiler autovectorizes your code)

Current compilers are good enough to do the right thing (i.e., your code will not be slow, memcpy is recognized, and will be handled well).

geza
  • 28,403
  • 6
  • 61
  • 135
1

Some architectures require the read to be aligned to work. They throw a processor signal if the alignment is incorrect.

Depending on the platform it can

  1. Crash the program
  2. Cause a re-run with an unaligned read. (Performance hit)
  3. Just work correctly

Performing a performance measure is a good start, and checking the OS specifications for your target platform would be prudent.

mksteve
  • 12,614
  • 3
  • 28
  • 50