title: Can GCC be coerced to generate efficient constructors for memory-aligned objects?
body: <p>I'm optimizing a constructor that is called in one of our app's innermost loops. The class in question is about 100 bytes wide, consists of a bunch of <code>int</code>s, <code>float</code>s, <code>bool</code>s, and trivial structs, and should be trivially copyable (it has a nontrivial default constructor, but no destructor or virtual functions). It is constructed often enough that every <em>nanosecond</em> of time spent in this ctor works out to around $6,000 of extra server hardware we need to buy.</p>
  
  <p>However, I find that GCC is not emitting very efficient code for this constructor (even with <code>-O3 -march</code> etc set). GCC's implementation of the constructor, filling out default values via an initializer list, takes about 34ns to run. If instead of this default constructor I use a hand-written function that writes directly to the object's memory space with a variety of SIMD intrinsics and pointer math, construction takes about 8ns.</p>
  
  <p>Can I get GCC to emit an efficient constructor for such objects when I <a href="http://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Type-Attributes.html" rel="noreferrer"><code>__attribute__</code></a> them to be memory-aligned on SIMD boundaries? Or must I resort to old-school techniques like writing my own memory initializers in assembly? </p>
  
  <p>This object is only ever constructed as a local on the stack, so any new/malloc overhead doesn't apply.</p>
  
  <p><strong>Context:</strong></p>
  
  <p>This class is used by constructing it on the stack as a local variable, selectively writing a few fields with non-default values, and then passing it (by reference) to a function, which passes its reference to another and so on.</p>
  
  <pre><code>struct Trivial {
    float x,y,z;
    Trivial () : x(0), y(0), z(0) {};
  };
  
  struct Frobozz
  {
     int na,nb,nc,nd;
     bool ba,bb,bc;
     char ca,cb,cc;
     float fa,fb;
     Trivial va, vb; // in the real class there's several different kinds of these
     // and so on
     Frobozz() : na(0), nb(1), nc(-1), nd(0),
                 ba(false), bb(true), bc(false),
                 ca('a'), cb('b'), cc('c'),
                 fa(-1), fb(1.0) // etc
      {}
  } __attribute__(( aligned(16) ));
  
  // a pointer to a func that takes the struct by reference
  typedef int (*FrobozzSink_t)( Frobozz&amp; );
  
  // example of how a function might construct one of the param objects and send it
  // to a sink. Imagine this is one of thousands of event sources:
  int OversimplifiedExample( int a, float b )
  {
     Frobozz params; 
     params.na = a; params.fb = b; // other fields use their default values
     FrobozzSink_t funcptr = AssumeAConstantTimeOperationHere();
     return (*funcptr)(params);
  }
  </code></pre>
  
  <p>The optimal constructor here would work by copying from a static "template" instance into the freshly constructed instance, ideally using SIMD operators to work 16 bytes at a time. Instead GCC does exactly the wrong thing for OversimplifiedExample() &mdash; a series of immediate mov ops to fill out the struct byte-by-byte.</p>
  
  <pre><code>// from objdump -dS
  int OversimplifiedExample( int a, float b )
  {
       a42:55                   push   %ebp
       a43:89 e5                mov    %esp,%ebp
       a45:53                   push   %ebx
       a46:e8 00 00 00 00       call   a4b &lt;_Z21OversimplifiedExampleif+0xb&gt;
       a4b:5b                   pop    %ebx
       a4c:81 c3 03 00 00 00    add    $0x3,%ebx
       a52:83 ec 54             sub    $0x54,%esp
       // calling the 'Trivial()' constructors which move zero, word by word...
       a55:89 45 e0             mov    %eax,-0x20(%ebp)
       a58:89 45 e4             mov    %eax,-0x1c(%ebp)
       a5b:89 45 e8             mov    %eax,-0x18(%ebp)
       a5e:89 45 ec             mov    %eax,-0x14(%ebp)
       a61:89 45 f0             mov    %eax,-0x10(%ebp)
       a64:89 45 f4             mov    %eax,-0xc(%ebp)
       // filling out na/nb/nc/nd..
       a67:c7 45 c4 01 00 00 00 movl   $0x1,-0x3c(%ebp)
       a71:c7 45 c8 ff ff ff ff movl   $0xffffffff,-0x38(%ebp)
       a78:89 45 c0             mov    %eax,-0x40(%ebp)
       a7b:c7 45 cc 00 00 00 00 movl   $0x0,-0x34(%ebp)
       a82:8b 45 0c             mov    0xc(%ebp),%eax
       // doing the bools and chars by moving one immediate byte at a time!
       a85:c6 45 d0 00          movb   $0x0,-0x30(%ebp)
       a89:c6 45 d1 01          movb   $0x1,-0x2f(%ebp)
       a8d:c6 45 d2 00          movb   $0x0,-0x2e(%ebp)
       a91:c6 45 d3 61          movb   $0x61,-0x2d(%ebp)
       a95:c6 45 d4 62          movb   $0x62,-0x2c(%ebp)
       a99:c6 45 d5 63          movb   $0x63,-0x2b(%ebp)
       // now the floats...
       a9d:c7 45 d8 00 00 80 bf movl   $0xbf800000,-0x28(%ebp)
       aa4:89 45 dc             mov    %eax,-0x24(%ebp)
       // FrobozzSink_t funcptr = GetFrobozz();
       aa7:e8 fc ff ff ff       call   aa8 &lt;_Z21OversimplifiedExampleif+0x68&gt;
       // return (*funcptr)(params);
       aac:8d 55 c0             lea    -0x40(%ebp),%edx
       aaf:89 14 24             mov    %edx,(%esp)
       ab2:ff d0                call   *%eax
       ab4:83 c4 54             add    $0x54,%esp
       ab7:5b                   pop    %ebx
       ab8:c9                   leave 
       ab9:c3                   ret   
  }
  </code></pre>
  
  <p>I tried to encourage GCC to construct a single 'default template' of this object, and then bulk-copy it in the default constructor, by doing a bit of trickery with a hidden 'dummy' constructor that made the base exemplar and then having the default just copy it:</p>
  
  <pre><code>struct Frobozz
  {
       int na,nb,nc,nd;
       bool ba,bb,bc;
       char ca,cb,cc;
       float fa,fb;
       Trivial va, vb;
       inline Frobozz();
  private:
       // and so on
       inline Frobozz( int dummy ) : na(0), /* etc etc */     {}
  } __attribute__( ( aligned( 16 ) ) );
  
  Frobozz::Frobozz( )
  {
       const static Frobozz DefaultExemplar( 69105 );
       // analogous to copy-on-write idiom
       *this = DefaultExemplar;
       // or:
       // memcpy( this, &amp;DefaultExemplar, sizeof(Frobozz) );
  }
  </code></pre>
  
  <p>But this generated even <em>slower</em> code than the basic default with initializer list, due to some redundant stack copying.</p>
  
  <p>Finally I resorted to writing an inlined free function to do the <code>*this = DefaultExemplar</code> step, using compiler intrinsics and assumptions about memory alignment to issue <a href="http://en.wikipedia.org/wiki/Software_pipelining" rel="noreferrer">pipelined</a> <a href="http://www.jaist.ac.jp/iscenter-new/mpc/altix/altixdata/opt/intel/vtune/doc/users_guide/mergedProjects/analyzer_ec/mergedProjects/reference_olh/mergedProjects/instructions/instruct32_hh/vc183.htm" rel="noreferrer">MOVDQA</a> SSE2 opcodes that copy the struct efficiently. This got me the performance I need, but it's icky. I thought my days of writing initializers in assembly were behind me, and I'd really rather just have GCC's optimizer emit the right code in the first place.</p>
  
  <p><strong>Is there some way I can get GCC to generate optimal code for my constructor, some compiler setting or additional <code>__attribute__</code> I've missed?</strong></p>
  
  <p>This is GCC 4.4 running on Ubuntu. Compiler flags include <code>-m32 -march=core2 -O3 -fno-strict-aliasing -fPIC</code> (among others). Portability is <em>not</em> a consideration, and I'm thoroughly willing to sacrifice standards-compliance for performance here.</p>
  
  <p>Timings were performed by directly reading the time stamp counter with <code>rdtsc</code>, <em>eg</em> measuring a loop of <strong><em>N</em></strong> OversimplifiedExample() calls between samples with due attention to timer resolution and cache and statistical significance and so on.</p>
  
  <p>I've also optimized this by reducing the number of call sites as much as possible, of course, but I'd still like to know how to generally get better ctors out of GCC.</p>