Looks great, thanks!

-shire

On Dec 20, 2007, at 5:22 AM, Dmitry Stogov wrote:

Hi Brain,

I've committed your patch into all branches, because it not only improve performance on x86_64, but also fixes a bug in x86 code.

Thank you very much.

Dmitry.

-------- Original Message --------
Subject: [PHP-DEV] PATCH: zend_alloc.c x86_64 optimization
Date: Wed, 28 Nov 2007 14:27:29 -0800
From: Brian Shire <[EMAIL PROTECTED]>
To: internals@lists.php.net
I noticed that there where some x86_64 assembly optimizations missing
from Zend/zend_alloc.c, it only accounts for i386.  The following
patch should add x86_64 support (I don't have karma for Zend of
course, patch is against 5.2.5), I've included a bench mark with a
simple test script to test out memory allocation.  I'd be interested
in getting feedback on this and knowing what other's results are.
Sorry for the custom micro-bench but zend_bench.php did show small
gains, but they where extremely small to really show anything.
A note on the i386 assembly, I had to add the following '&' char to
make sure the input/outputs are using different registers.  Lack of
this had caused some serious memory corruption on my system with -O2
so I'm guessing it might be appropriate to do the same on the i386
code as well, but I've left that out of this patch, perhaps someone
with some assembler experience can verify this is correct?
-                    : "=a"(res), "=d" (overflow)
+                    : "=&a"(res), "=&d" (overflow)
Thanks,
-shire
<?php
$start = microtime(true);
for($i=0; $i< 1000000; $i++) {
  $x[$i] = 'xxxxx';
}
$stop = microtime(true);
print ($stop-$start)."\n";
?>
php-5.2.5
-----------
    no-asm        asm        delta
-----------------------------------------------------
Run1    0.926729918    0.767436981    -0.159292936
Run2    0.920269966    0.768045902    -0.152224064
Run3    0.918609858    0.758006096    -0.160603762
Total    2.765609741    2.293488979    -0.472120762
Percentage:                -17.07%
Index: Zend/zend_alloc.c
===================================================================
--- Zend/zend_alloc.c    (revision 69567)
+++ Zend/zend_alloc.c    (working copy)
@@ -656,6 +656,11 @@
     __asm__("bsrl %1,%0\n\t" : "=r" (n) : "rm"  (_size));
     return n;
+#elif defined(__GNUC__) && defined(__x86_64__)
+    unsigned long n;
+
+    __asm__("bsrq %1,%0\n\t" : "=r" (n) : "rm" (_size));
+    return (unsigned int)n;
 #elif defined(_MSC_VER) && defined(_M_IX86)
     __asm {
         bsr eax, _size
@@ -677,6 +682,11 @@
     __asm__("bsfl %1,%0\n\t" : "=r" (n) : "rm"  (_size));
     return n;
+#elif defined(__GNUC__) && defined(__x86_64__)
+    unsigned long n;
+
+    __asm__("bsfq %1,%0\n\t" : "=r" (n) : "rm" (_size));
+  return (unsigned int)n;
 #elif defined(_MSC_VER) && defined(_M_IX86)
     __asm {
         bsf eax, _size
@@ -2309,18 +2319,30 @@
     return _zend_mm_block_size(AG(mm_heap), ptr
ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
 }
-#if defined(__GNUC__) && defined(i386)
+#if defined(__GNUC__) && (defined(i386) || defined(__x86_64__))
 static inline size_t safe_address(size_t nmemb, size_t size, size_t
offset)
 {
     size_t res = nmemb;
-    unsigned long overflow ;
+    unsigned long overflow = 0;
-    __asm__ ("mull %3\n\taddl %4,%0\n\tadcl $0,%1"
+#if defined(i386)
+    __asm__ (    "mull %3    \n\t"
+                        "addl %4,%0 \n\t"
+                        "adcl $0,%1 \n\t"
          : "=a"(res), "=d" (overflow)
          : "%0"(res),
            "rm"(size),
            "rm"(offset));
+#else /* __x86_64__ */
+    __asm__ (    "mulq %3     \n\t"
+                        "addq %4,%0  \n\t"
+                        "adcq $0,%1  \n\t"
+                    : "=&a"(res), "=&d" (overflow)
+                    : "%0"(res),
+                        "rm"(size),
+                        "rm"(offset) );
+#endif
         if (UNEXPECTED(overflow)) {
zend_error_noreturn(E_ERROR, "Possible integer overflow in memory
allocation (%zu * %zu + %zu)", nmemb, size, offset);

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to