Re: Switch jumptable optimization

From: Date: Mon, 16 Feb 2015 23:30:21 +0000
Subject: Re: Switch jumptable optimization
References: 1  Groups: php.internals 
Request: Send a blank email to internals+get-82902@lists.php.net to get a copy of this message
On 02/16/2015 03:04 PM, Bob Weinand wrote: > I'd like to show you my recent work on a jumptable optimization for switches. > > https://github.com/php/php-src/pull/1048 > <https://github.com/php/php-src/pull/1048> > > It is a fully transparent optimization of switches, by putting a new ZEND_SWITCH opcode at the > top of the switch in case we can build a jumptable, which is the case if the cases are only scalars > (no doubles) or evaluate to them at compile-time. > > Switches tend to be big sometimes with a lot of static (literals or constants usually) cases, > which was a comparison for each case, and now just a simple hashtable lookup is needed, which > greatly improves performance. In case where the result of the switch can be determined at > compile-time, it even replaces the comparisons with a simple ZEND_JMP opcode. > > In synthetic benchmarks the results are mind blowing, but in practice, benefits mostly are > stateful userland parsers (often called with sometimes big switches), where it makes it a few > percent faster. (For more concrete numbers see > https://github.com/php/php-src/pull/1048#issuecomment-73032647) > > As the optimization is only done if there are 3 or more cases, the lookup is always faster than > the single comparisons. So there's no negative performance impact. > > It already works, except with opcache where the CFG optimization pass still lacks support. > Dmitry or Laruence volunteered to add support for opcache. > > I'd like to know if there are any technical objections to the PR. If not, they will add > opcache support and merge it in. It looks ok to me if Xinchen or Dmitry gets the opcache support working for it and the feature is stabilized in time. I gave it a try and it is segfaulting for me (no opcache): ==5612== Command: sapi/cli/php -n jump.php ==5612== ==5612== Invalid read of size 4 ==5612== at 0xA64637: _zend_is_inconsistent (zend_hash.c:44) ==5612== by 0xA65749: _zend_hash_add_or_update_i (zend_hash.c:427) ==5612== by 0xA65AF9: _zend_hash_add (zend_hash.c:489) ==5612== by 0xA37E28: zend_hash_add_ptr (zend_hash.h:458) ==5612== by 0xA39B0A: zend_hash_add_constant (zend_constants.c:486) ==5612== by 0xA39D01: zend_register_constant (zend_constants.c:523) ==5612== by 0xA389E9: zend_register_long_constant (zend_constants.c:194) ==5612== by 0xA3855C: zend_register_standard_constants (zend_constants.c:116) ==5612== by 0xA52D6E: zend_startup (zend.c:671) ==5612== by 0x9C7FAA: php_module_startup (main.c:2099) ==5612== by 0xAFA460: php_cli_startup (php_cli.c:421) ==5612== by 0xAFC4D6: main (php_cli.c:1335) ==5612== Address 0x8 is not stack'd, malloc'd or (recently) free'd And jump.php is: <?php $a = 1; switch($a) { case 0: echo 0; break; case 1: echo 1; break; case 2: echo 1; break; case 3: echo 1; break; case 4: echo 1; break; case 5: echo 1; break; case 6: echo 1; break; case 7: echo 1; break; case 8: echo 1; break; case 9: echo 1; break; } -Rasmus

Attachment: [application/pgp-signature] OpenPGP digital signature signature.asc
« previous php.internals (#82902) next »