Note that there are some explanatory texts on larger screens.

plurals
  1. POReason for ~100x slowdown with heap memory functions using HEAP_NO_SERIALIZE on Windows Vista and Windows 7
    text
    copied!<p>I'm trying to tracedown a huge slowdown in the heap memory functions in Windows Vista and Windows 7 (I didn't test on any server editions). It doesn't happen on Windows XP at all, only on Microsoft's newer operating systems.</p> <p>I originally ran into this problem with PHP complied on Windows. The scripts themselves seemed to run at the expected speed, but after script execution I was experiencing 1-2 seconds of delay in the internal PHP shutdown functions. After firing up the debugging I saw that it had to do with the PHP memory manager's use of <code>HeapAlloc</code>/<code>HeapFree</code>/<code>HeapReAlloc</code>.</p> <p>I traced it down to the use of the flag <code>HEAP_NO_SERIALIZE</code> on the heap functions:</p> <pre><code>#ifdef ZEND_WIN32 #define ZEND_DO_MALLOC(size) (AG(memory_heap) ? HeapAlloc(AG(memory_heap), HEAP_NO_SERIALIZE, size) : malloc(size)) #define ZEND_DO_FREE(ptr) (AG(memory_heap) ? HeapFree(AG(memory_heap), HEAP_NO_SERIALIZE, ptr) : free(ptr)) #define ZEND_DO_REALLOC(ptr, size) (AG(memory_heap) ? HeapReAlloc(AG(memory_heap), HEAP_NO_SERIALIZE, ptr, size) : realloc(ptr, size)) #else #define ZEND_DO_MALLOC(size) malloc(size) #define ZEND_DO_FREE(ptr) free(ptr) #define ZEND_DO_REALLOC(ptr, size) realloc(ptr, size) #endif </code></pre> <p>and (which actually sets the default for <code>HeapAlloc</code>/<code>HeapFree</code>/<code>HeapReAlloc</code>) in the function <code>start_memory_manager</code>:</p> <pre><code>#ifdef ZEND_WIN32 AG(memory_heap) = HeapCreate(HEAP_NO_SERIALIZE, 256*1024, 0); #endif </code></pre> <p>I removed the <code>HEAP_NO_SERIALIZE</code> parameter (replaced with 0), and it fixed the problem. Scripts now cleanup quickly in both the CLI and the SAPI Apache 2 version. This was for PHP 4.4.9, but the PHP 5 and 6 source code (in development) contains the same flag on the calls.</p> <p>I'm not sure if what I did was dangerous or not. It's all a part of the PHP memory manager, so I'm going to have to do some digging and research, but this brings up the question:</p> <p><strong>Why are the heap memory function so slow on Windows Vista and Windows 7 with <code>HEAP_NO_SERIALIZE</code>?</strong></p> <p>While researching this problem I came up with exactly one good hit. Please read the blog post <a href="http://www.brainfarter.net/?p=69" rel="nofollow noreferrer">http://www.brainfarter.net/?p=69</a> where the poster explains the issue and offers a test case (both source and binaries available) to highlight the issue.</p> <p>My tests on a Windows 7 x64 quad core 8&nbsp;GB machine gives <strong>43,836</strong>. Ouch! The same results without the <code>HEAP_NO_SERIALIZE</code> flag is <strong>655</strong>, ~70x faster in my case.</p> <p>Lastly, it seems that any program created with Visual C++ 6 using <code>malloc</code>/<code>free</code> or <code>new</code>/<code>delete</code> seems to be affected on these newer platforms. The Visual C++ 2008 compiler doesn't set this flag by default for those functions/operators so they aren't affected -- but that still leaves a lot of programs affected!</p> <p>I encourage you to download the proof of concept and give this a try. This problem explained why my normal PHP on Windows installation was crawling and may explain why Windows Vista and Windows 7 seems slower at times.</p> <p><strong>UPDATE 2010-01-26:</strong> I received a response from Microsoft stating that the <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa366750%28v=vs.85%29.aspx" rel="nofollow noreferrer">low-fragmentation heap</a> (LFH) is the de facto default policy for heaps that hold any appreciable number of allocations. In Windows Vista, they reorganized a lot of code to remove extra data structures and code paths that were no longer part of the common case for handling heap API calls. With the <code>HEAP_NO_SERIALIZE</code> flag and in certain debugging situations, they do not allow the use of the LFH and we get stuck on the slow and less optimized path through the heap manager. So... it's highly recommended to not use <code>HEAP_NO_SERIALIZE</code> since you'll miss out on all the work to the LFH and any future work in the Windows heap API.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload