Skip to content

Commit 79a84e0

Browse files
Sebastian Popdstogov
Sebastian Pop
authored andcommitted
speed up increment and decrement operators with overflow detection
On A72, google-benchmark measure before and after the patch: -------------------------------------------------------- Benchmark Time CPU Iterations -------------------------------------------------------- BM_inc_before 6.54 ns 6.54 ns 106985447 BM_dec_before 6.54 ns 6.54 ns 107011667 BM_inc_after 4.36 ns 4.36 ns 160525864 BM_dec_after 4.36 ns 4.36 ns 160524243 Before the patch: fast_long_add_function: ldr x0, [x1] add x2, x0, 1 cmp x2, x0 blt .L11 str x2, [x1] ret .L11: mov x0, 4890909195324358656 mov w2, 5 str x0, [x1] str w2, [x1, 8] ret With the patch: fast_long_add_function: ldr x5, [x1] adds x5,x5,1 bvs .L2 str x5, [x1] ret .L2: mov x0, 4890909195324358656 mov w2, 5 str x0, [x1] str w2, [x1, 8] ret php$ ./sapi/cli/php Zend/bench.php Base: Patch: simple 0.091 simple 0.091 simplecall 0.014 simplecall 0.014 simpleucall 0.041 simpleucall 0.041 simpleudcall 0.045 simpleudcall 0.045 mandel 0.193 mandel 0.193 mandel2 0.229 mandel2 0.229 ackermann(7) 0.044 ackermann(7) 0.044 ary(50000) 0.010 ary(50000) 0.010 ary2(50000) 0.008 ary2(50000) 0.008 ary3(2000) 0.096 ary3(2000) 0.102 fibo(30) 0.149 fibo(30) 0.148 hash1(50000) 0.016 hash1(50000) 0.016 hash2(500) 0.020 hash2(500) 0.020 heapsort(20000) 0.055 heapsort(20000) 0.055 matrix(20) 0.057 matrix(20) 0.057 nestedloop(12) 0.091 nestedloop(12) 0.091 sieve(30) 0.032 sieve(30) 0.032 strcat(200000) 0.010 strcat(200000) 0.010 ------------------------ ------------------------ Total 1.199 Total 1.204 php$ ./sapi/cli/php Zend/micro_bench.php Base: Patch: empty_loop 0.051 empty_loop 0.050 func() 0.181 0.130 func() 0.181 0.131 undef_func() 0.186 0.135 undef_func() 0.186 0.136 int_func() 0.116 0.064 int_func() 0.116 0.065 $x = self::$x 0.235 0.183 $x = self::$x 0.229 0.179 self::$x = 0 0.198 0.147 self::$x = 0 0.199 0.148 isset(self::$x) 0.229 0.178 isset(self::$x) 0.225 0.174 empty(self::$x) 0.231 0.180 empty(self::$x) 0.227 0.177 $x = Foo::$x 0.144 0.093 $x = Foo::$x 0.142 0.092 Foo::$x = 0 0.107 0.056 Foo::$x = 0 0.105 0.054 isset(Foo::$x) 0.140 0.088 isset(Foo::$x) 0.140 0.089 empty(Foo::$x) 0.148 0.097 empty(Foo::$x) 0.144 0.094 self::f() 0.238 0.187 self::f() 0.240 0.190 Foo::f() 0.209 0.158 Foo::f() 0.201 0.150 $x = $this->x 0.123 0.072 $x = $this->x 0.120 0.070 $this->x = 0 0.124 0.073 $this->x = 0 0.124 0.074 $this->x += 2 0.151 0.099 $this->x += 2 0.151 0.101 ++$this->x 0.137 0.086 ++$this->x 0.139 0.088 --$this->x 0.137 0.086 --$this->x 0.137 0.087 $this->x++ 0.170 0.119 $this->x++ 0.172 0.122 $this->x-- 0.171 0.119 $this->x-- 0.172 0.122 isset($this->x) 0.170 0.119 isset($this->x) 0.170 0.120 empty($this->x) 0.179 0.128 empty($this->x) 0.179 0.129 $this->f() 0.194 0.143 $this->f() 0.194 0.144 $x = Foo::TEST 0.188 0.137 $x = Foo::TEST 0.188 0.138 new Foo() 0.482 0.431 new Foo() 0.482 0.432 $x = TEST 0.109 0.058 $x = TEST 0.109 0.059 $x = $_GET 0.190 0.138 $x = $_GET 0.188 0.137 $x = $GLOBALS['v'] 0.242 0.191 $x = $GLOBALS['v'] 0.246 0.196 $x = $hash['v'] 0.196 0.145 $x = $hash['v'] 0.192 0.142 $x = $str[0] 0.146 0.094 $x = $str[0] 0.142 0.092 $x = $a ?: null 0.144 0.093 $x = $a ?: null 0.144 0.094 $x = $f ?: tmp 0.174 0.123 $x = $f ?: tmp 0.174 0.124 $x = $f ? $f : $a 0.153 0.101 $x = $f ? $f : $a 0.153 0.102 $x = $f ? $f : tmp 0.148 0.097 $x = $f ? $f : tmp 0.148 0.098 ------------------------ ------------------------ Total 6.143 Total 6.108
1 parent adc3b72 commit 79a84e0

File tree

1 file changed

+26
-0
lines changed

1 file changed

+26
-0
lines changed

Zend/zend_operators.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,19 @@ overflow: ZEND_ATTRIBUTE_COLD_LABEL
490490
return;
491491
overflow: ZEND_ATTRIBUTE_COLD_LABEL
492492
ZVAL_DOUBLE(op1, (double)ZEND_LONG_MAX + 1.0);
493+
#elif defined(HAVE_ASM_GOTO) && defined(__aarch64__)
494+
__asm__ goto (
495+
"ldr x5, [%0]\n\t"
496+
"adds x5, x5, 1\n\t"
497+
"bvs %l1\n"
498+
"str x5, [%0]"
499+
:
500+
: "r"(&op1->value)
501+
: "x5", "cc", "memory"
502+
: overflow);
503+
return;
504+
overflow: ZEND_ATTRIBUTE_COLD_LABEL
505+
ZVAL_DOUBLE(op1, (double)ZEND_LONG_MAX + 1.0);
493506
#elif PHP_HAVE_BUILTIN_SADDL_OVERFLOW && SIZEOF_LONG == SIZEOF_ZEND_LONG
494507
long lresult;
495508
if (UNEXPECTED(__builtin_saddl_overflow(Z_LVAL_P(op1), 1, &lresult))) {
@@ -540,6 +553,19 @@ overflow: ZEND_ATTRIBUTE_COLD_LABEL
540553
return;
541554
overflow: ZEND_ATTRIBUTE_COLD_LABEL
542555
ZVAL_DOUBLE(op1, (double)ZEND_LONG_MIN - 1.0);
556+
#elif defined(HAVE_ASM_GOTO) && defined(__aarch64__)
557+
__asm__ goto (
558+
"ldr x5, [%0]\n\t"
559+
"subs x5 ,x5, 1\n\t"
560+
"bvs %l1\n"
561+
"str x5, [%0]"
562+
:
563+
: "r"(&op1->value)
564+
: "x5", "cc", "memory"
565+
: overflow);
566+
return;
567+
overflow: ZEND_ATTRIBUTE_COLD_LABEL
568+
ZVAL_DOUBLE(op1, (double)ZEND_LONG_MIN - 1.0);
543569
#elif PHP_HAVE_BUILTIN_SSUBL_OVERFLOW && SIZEOF_LONG == SIZEOF_ZEND_LONG
544570
long lresult;
545571
if (UNEXPECTED(__builtin_ssubl_overflow(Z_LVAL_P(op1), 1, &lresult))) {

0 commit comments

Comments
 (0)