Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:33488 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 5020 invoked by uid 1010); 28 Nov 2007 22:27:37 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 5003 invoked from network); 28 Nov 2007 22:27:37 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 28 Nov 2007 22:27:37 -0000 Authentication-Results: pb1.pair.com smtp.mail=shire@php.net; spf=unknown; sender-id=unknown Authentication-Results: pb1.pair.com header.from=shire@php.net; sender-id=unknown Received-SPF: unknown (pb1.pair.com: domain php.net does not designate 69.63.177.213 as permitted sender) X-PHP-List-Original-Sender: shire@php.net X-Host-Fingerprint: 69.63.177.213 sizzo.org Received: from [69.63.177.213] ([69.63.177.213:40129] helo=sizzo.org) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 9B/B1-19722-65BED474 for ; Wed, 28 Nov 2007 17:27:36 -0500 Received: from [172.21.211.59] (unknown [204.15.20.249]) (using TLSv1 with cipher AES128-SHA (128/128 bits)) (No client certificate requested) by sizzo.org (Postfix) with ESMTP id 0216A5272B3 for ; Wed, 28 Nov 2007 14:20:09 -0800 (PST) Mime-Version: 1.0 (Apple Message framework v752.3) Content-Transfer-Encoding: 7bit Message-ID: <0ADA78C9-CE10-4B8B-8FCA-33AB24DA9C80@php.net> Content-Type: text/plain; charset=US-ASCII; delsp=yes; format=flowed To: internals@lists.php.net Date: Wed, 28 Nov 2007 14:27:29 -0800 X-Mailer: Apple Mail (2.752.3) Subject: PATCH: zend_alloc.c x86_64 optimization From: shire@php.net (Brian Shire) 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-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);