title: Take advantage of ARM unaligned memory access while writing clean C code
body: <p>It used to be that ARM processors were unable to properly handle unaligned memory access (ARMv5 and below). Something like <code>u32 var32 = *(u32*)ptr;</code> would just fail (raise exception) if <code>ptr</code> was not properly aligned on 4-bytes.</p>
  
  <p>Writing such a statement would work fine for x86/x64 though, since these CPU have always handled such situation very efficiently. But according to C standard, this is not a "proper" way to write it. <code>u32</code> is apparently equivalent to a structure of 4 bytes which <em>must</em> be aligned on 4 bytes.</p>
  
  <p>A proper way to achieve the same result while keeping the orthodoxy correctness <em>and</em> ensuring full compatibility with any cpu is : </p>
  
  <pre><code>u32 read32(const void* ptr) 
  { 
      u32 result; 
      memcpy(&amp;result, ptr, 4); 
      return result; 
  }
  </code></pre>
  
  <p>This one is correct, will generate proper code for any cpu able or not to read at unaligned positions. Even better, on x86/x64, it's properly optimized to a single read operation, hence has the same performance as the first statement. It's portable, safe, and fast. Who can ask more ?</p>
  
  <p>Well, problem is, on ARM, we are not so lucky.</p>
  
  <p>Writing the <code>memcpy</code> version is indeed safe, but seems to result in systematic cautious operations, which are very slow for ARMv6 and ARMv7 (basically, any smartphone).</p>
  
  <p>In a performance oriented application which heavily relies on read operations, the difference between the 1st and 2nd version could be measured : it stands at  <strong>> 5x</strong> at <code>gcc -O2</code> settings. This is way too much to be ignored.</p>
  
  <p>Trying to find a way to use ARMv6/v7 capabilities, I've looked for guidance on a few example codes around. Unfortunatley, they seem to select the first statement (direct <code>u32</code> access), which is not supposed to be correct.</p>
  
  <p>That's not all : new GCC versions are now trying to implement auto-vectorization. On x64, that means SSE/AVX, on ARMv7 that means NEON. ARMv7 also supports some new "Load Multiple" (LDM) and "Store Multiple" (STM) opcodes, which <em>require</em> pointer to be aligned.</p>
  
  <p>What does that mean ? Well, the compiler is free to use these advanced instructions, even if they were not specifically called from the C code (no intrinsic). To take such decision, it uses the fact the an <code>u32* pointer</code> is supposed to be aligned on 4 bytes. If it's not, then all bets are off : undefined behavior, crashes.</p>
  
  <p>What that means is that even on CPU which support unaligned memory access, it's now dangerous to use direct <code>u32</code> access, as it can lead to buggy code generation at high optimization settings (<code>-O3</code>).</p>
  
  <p>So now, this is a dilemna : how to access the native performance of ARMv6/v7 on unaligned memory access <em>without</em> writing the incorrect version <code>u32</code> access ?</p>
  
  <p>PS : I've also tried <code>__packed()</code> instructions, and from a performance perspective, they seem to work exactly the same as the <code>memcpy</code> method.</p>
  
  <p><em>[Edit] :</em> Thanks for the excellent elements received so far.</p>
  
  <p>Looking at the generated assembly, I could confirm @Notlikethat finding that <code>memcpy</code> version does indeed generate proper <code>ldr</code> opcode (unaligned load). However, I also found that the generated assembly uselessly invokes <code>str</code> (command). So the complete operation is now an unaligned load, an aligned store, and then a final aligned load. That's a lot more work than necessary.</p>
  
  <p>Answering @haneefmubarak, yes the code is properly inlined. And no, <code>memcpy</code> is very far from providing the best possible speed, since forcing the code to accept direct <code>u32</code> access translates into huge performance gains. So some better possibility must exist.</p>
  
  <p>A big thank to @artless_noise. The link to godbolt service is unvaluable. I've never been able to see so clearly the equivalence between a C source code and its assembly representation. This is highly inspiring.</p>
  
  <p>I completed one of @artless examples, and it gives the following :</p>
  
  <pre><code>#include &lt;stdlib.h&gt;
  #include &lt;memory.h&gt;
  typedef unsigned int u32;
  
  u32 reada32(const void* ptr) { return *(const u32*) ptr; }
  
  u32 readu32(const void* ptr) 
  { 
      u32 result; 
      memcpy(&amp;result, ptr, 4); 
      return result; 
  }
  </code></pre>
  
  <p>once compiled using ARM GCC 4.8.2 at -O3 or -O2 :</p>
  
  <pre><code>reada32(void const*):
      ldr r0, [r0]
      bx  lr
  readu32(void const*):
      ldr r0, [r0]    @ unaligned
      sub sp, sp, #8
      str r0, [sp, #4]    @ unaligned
      ldr r0, [sp, #4]
      add sp, sp, #8
      bx  lr
  </code></pre>
  
  <p>Quite telling ....</p>