]> granicus.if.org Git - php/commitdiff
opcache: Patch SSE based fast_memcpy() implementation
authorBogdan Andone <bogdan.andone@intel.com>
Wed, 29 Jul 2015 11:19:04 +0000 (14:19 +0300)
committerBogdan Andone <bogdan.andone@intel.com>
Wed, 29 Jul 2015 11:51:57 +0000 (14:51 +0300)
Use _mm_store_si128() instead of _mm_stream_si128(). This ensures that copied memory
is preserved in data cache, which is good as the interpretor will start to use this
data without the need to go back to memory. _mm_stream* is intended to be used for
stores where we want to avoid reading data into the cache and the cache pollution;
in our scenario it seems that preserving the data in cache has a positive impact.

Tests on WordPress 4.1 show ~1% performance increase with fast_memcpy() in place
versus standard memcpy() when running php-cgi -T10000 wordpress/index.php.

I also updated SW prefetching on target memory but its contribution is almost negligible.
The address to be prefetched will be used in a couple of cycles (at the next iteration)
while the data from memory will be available in >100 cycles.

ext/opcache/zend_accelerator_util_funcs.c

index e20f3d16f6141a7cc4ba50a4423b202dc2d14c1b..cfb03a00e40f5d8eb7ccde6dd28506bff00bf19a 100644 (file)
@@ -658,16 +658,17 @@ static zend_always_inline void fast_memcpy(void *dest, const void *src, size_t s
 
        do {
                _mm_prefetch(dqsrc + 4, _MM_HINT_NTA);
+               _mm_prefetch(dqdest + 4, _MM_HINT_T0);
 
                __m128i xmm0 = _mm_load_si128(dqsrc + 0);
                __m128i xmm1 = _mm_load_si128(dqsrc + 1);
                __m128i xmm2 = _mm_load_si128(dqsrc + 2);
                __m128i xmm3 = _mm_load_si128(dqsrc + 3);
                dqsrc  += 4;
-               _mm_stream_si128(dqdest + 0, xmm0);
-               _mm_stream_si128(dqdest + 1, xmm1);
-               _mm_stream_si128(dqdest + 2, xmm2);
-               _mm_stream_si128(dqdest + 3, xmm3);
+               _mm_store_si128(dqdest + 0, xmm0);
+               _mm_store_si128(dqdest + 1, xmm1);
+               _mm_store_si128(dqdest + 2, xmm2);
+               _mm_store_si128(dqdest + 3, xmm3);
                dqdest += 4;
        } while (dqsrc != end);
 }