title: Why does the same for loop runs faster in the second time?
body: <p>Initially I was comparing performance of built-in D arrays and plain pointers, but I've ended up with a different issue. For some reason if I run two identical for loops one after another, the second one always completes faster.</p>
  
  <p>Here is the code:</p>
  
  <pre><code>import std.stdio : writeln;
  import std.datetime : StopWatch;
  import core.stdc.stdlib : malloc, free;
  
  void main()
  {
      immutable N = 1_000_000_000;
      StopWatch sw;
  
      uint* ptr = cast(uint*)malloc(uint.sizeof * N);
  
      sw.start();
      for (uint i = 0; i &lt; N; ++i)
          ptr[i] = 1;
      sw.stop();
      writeln("the first for loop time: ", sw.peek().msecs(), " msecs");
      sw.reset();
  
      sw.start();
      for (uint i = 0; i &lt; N; ++i)
          ptr[i] = 2;
      sw.stop();
      writeln("the second for loop time: ", sw.peek().msecs(), " msecs");
      sw.reset();
  
      free(ptr);
  }
  </code></pre>
  
  <p>After compiling and running it with <code>dmd -release -O -noboundscheck -inline test.d -of=test &amp;&amp; ./test</code> it prints:</p>
  
  <pre><code>the first for loop time: 1253 msecs
  the second for loop time: 357 msecs
  </code></pre>
  
  <p>I was not sure whether this is something related to D or dmd so I've rewritten this code in C++:</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;chrono&gt;
  
  int main()
  {
      const unsigned int N = 1000000000;
  
      unsigned int* ptr = (unsigned int*)malloc(sizeof(unsigned int) * N);
  
      auto start = std::chrono::high_resolution_clock::now();
      for (uint i = 0; i &lt; N; ++i)
          ptr[i] = 1;
      auto finish = std::chrono::high_resolution_clock::now();
      auto milliseconds = std::chrono::duration_cast&lt;std::chrono::milliseconds&gt;(finish-start);
      std::cout &lt;&lt; "the first for loop time: " &lt;&lt; milliseconds.count() &lt;&lt; " msecs" &lt;&lt; std::endl;
  
      start = std::chrono::high_resolution_clock::now();
      for (uint i = 0; i &lt; N; ++i)
          ptr[i] = 2;
      finish = std::chrono::high_resolution_clock::now();
      milliseconds = std::chrono::duration_cast&lt;std::chrono::milliseconds&gt;(finish-start);
      std::cout &lt;&lt; "the second for loop time: " &lt;&lt; milliseconds.count() &lt;&lt; " msecs" &lt;&lt; std::endl;
  
      free(ptr);
  }
  </code></pre>
  
  <p>and <code>g++ -O3 test.cpp -o test &amp;&amp; ./test</code> gives similar output:</p>
  
  <pre><code>the first for loop time: 1029 msecs
  the second for loop time: 349 msecs
  </code></pre>
  
  <p>The result is the same every time I run this code. Allocated data is too big to be cached. There is no branching points so no branching prediction issues should be involved. The memory is accessed at the same direct order at both loops so I guess this should not be related to the memory layout.</p>
  
  <p>So why does the second one runs faster than the first one?</p>