Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:92102 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 63585 invoked from network); 5 Apr 2016 14:00:50 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 5 Apr 2016 14:00:50 -0000 Authentication-Results: pb1.pair.com smtp.mail=cornelius.howl@gmail.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=cornelius.howl@gmail.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.214.179 as permitted sender) X-PHP-List-Original-Sender: cornelius.howl@gmail.com X-Host-Fingerprint: 209.85.214.179 mail-ob0-f179.google.com Received: from [209.85.214.179] ([209.85.214.179:36330] helo=mail-ob0-f179.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 7C/86-27948-F05C3075 for ; Tue, 05 Apr 2016 10:00:47 -0400 Received: by mail-ob0-f179.google.com with SMTP id j9so9760118obd.3 for ; Tue, 05 Apr 2016 07:00:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to:cc; bh=tyz+tkIJuYQORHJKXimKuNPzgpH3KD7SAwsTLvnl1S8=; b=m9cNKUE5jp5MeHJLcdxVCXgZGZyg8hqVDx7aVAXk9vWEZsMb8ufskYstxb4aLhs7Tn 63Hkv6+LXeRlEWxwtUrJ3kPIVCm1dgomPT+VJW+VkAnqHJmoutrxgpZQXurP6G0W1miZ dpJIqy6H40dS+sAwA8Y9DaK6VJsHIcH0IjBg5TZdqgM9LZi5bYgE/otHbd5MSFJjeJLx Pl/UKBBJdLDwKnUqg5HVmOvAXKeeeFfFczF3zvmpHf3sA7wAQ/xqrN+2lTQ++Sy9/bpN OZm4ewbFtgyz66R+rv1EbfKDF4oQ0IEBvhUjFuwetg6F34XfzexL0n7UUy8NCEHbrmM9 wIKA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:date:message-id:subject:from:to:cc; bh=tyz+tkIJuYQORHJKXimKuNPzgpH3KD7SAwsTLvnl1S8=; b=G4YPe3Hy7quCcZa0KYBz9zpgX49yEnp9h4pf5o1SmDKYoCfgGry0vdMV6D4aG1MhAd 5hXL94thc5wpWBPxA5begRmdaNABYD/AP0QeMaV4lubMpIiQuYi65gZsku+sjxLeXByQ sEDwFT1mbazc5JrYL4HVuiovgUld46K6EzuIVjB24vlWkX5MIxc6dw+rB0ecYpPt8PDc Djnfo8PXu+9hQ9d87vgKKANmIGkY16mMHt8QJr6CUCqRG4YspLbMURo2jSsyY06MCnkJ KZsFzHSSbcoKA5R/Iix0F3fopdBYnj2vULcSOgAWU/2HSPA/P4pKo+4mSSdOFj64MH3x BV0w== X-Gm-Message-State: AD7BkJLlzzRHECgQ8B4khjE6v1zeyl9waAChMLS2Ng2IDkQlUDfD7BUYbMxEsHCiSmyHgi4lutz4wT38fQJqLA== MIME-Version: 1.0 X-Received: by 10.182.33.6 with SMTP id n6mr5761084obi.28.1459864843833; Tue, 05 Apr 2016 07:00:43 -0700 (PDT) Received: by 10.157.7.194 with HTTP; Tue, 5 Apr 2016 07:00:43 -0700 (PDT) Date: Tue, 5 Apr 2016 22:00:43 +0800 Message-ID: To: Dmitry Stogov Cc: Xinchen Hui , Nikita Popov , Bob Weinand , Joe Watkins , internals Content-Type: multipart/alternative; boundary=089e0158a8366fdb4e052fbd4577 Subject: Re: Object getter method optimization From: cornelius.howl@gmail.com (Lin Yo-An) --089e0158a8366fdb4e052fbd4577 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Hi Dmitry, Glad to hear your news, I just checked your patch and I like the approach you've done. :] I'm also still working on this idea this week, the const value accessor support was just added today. And I guess we may also support setters in the future (if possible) my thought is: - I think the getter optimization is useful since getter methods are heavily used in a lot of application like Drupal (like hundreds) - If we could produce more information in compile-time, we can reduce more runtime cost when executing the opcode handler. This way, we can reduce the impact to the overall performance. - I found the first two bytes in zend_op_array produces a 2 bytes room on 32bit machine and even more on 64bit machine because the memory alignment (not sure if it could be optimzed when memory alignment optimization is not enabled with gcc) My first attempt was to add a new flag in op_array->type, however it's already full, all bits are used currently. I think we can either extend the op_array type to uint32 or just add a new zend_uchar field to save the information (from the 2 bytes room). And using cache slot to save the property offset information. This field will be not only for simple getters, but also for simple setters and functions return const or return values that are simplified to scalar value. Your thoughts? Cheers, Yo-An On Tue, Apr 5, 2016 at 7:29 PM, Dmitry Stogov wrote: > Hi Yo-An Lin, > > > I spent few hours working on your idea and came to the following path. > > > https://gist.github.com/dstogov/2221ffc21ac16311c958a4830dbcee0f > > > I tried to keep binary compatibility, minimize run-time checks overhead > and fix related problems and leaks. > > BTW I'm not sure, if I like the patch even in this state. > > > The patch significantly speed-ups getters (more than 2 times) in small > cost for all other methods, but the final effect on application may be > negative. > > Of course, we may add specialized opcode for INIT_METHOD_CALL without > arguments, that would almost completely eliminate overhead. > > > Anyway, I like to listen opinions: > > - if we should include such optimizations? > > - do you see any other applications to similar optimizations? > > > Thanks. Dmitry. > > > ------------------------------ > *From:* Lin Yo-An > *Sent:* Sunday, April 3, 2016 11:10 > *To:* Xinchen Hui > *Cc:* Dmitry Stogov; internals; Nikita Popov > *Subject:* Re: Object getter method optimization > > I submitted the new benchmark result here: > > Benchmark Result Getter Method Only > > https://gist.github.com/8cd230a5601cbe38439661adf3caca0d > > Without getter optimization (3 runs): > 151.0169506073ms > > With getter optimization (3 runs) > 39.201021194458ms > Template Engine Benchmark > > https://gist.github.com/a23cf294dfcf74683b8f02d93a47bc5b > > With getter optimization: > 1118ms > > Without getter optimization: > 1235ms > Affect > > Other Microbench result: > https://gist.github.com/c9s/0273ac21631562724cabf86c42e86e32 > > On Sat, Apr 2, 2016 at 11:29 AM, Lin Yo-An > wrote: > >> Hi Xinchen Hui, >> >> The magic get method is not being optimized. This optimization only >> focuses on simple getter, which is used in a lot of OO-based appoication= s >> like Symfony or Drupal. >> >> >> Hi Dimitry, >> >> Thanks for reviewing the code, comments are helpful. :) could you explai= n >> a little bit of how runtime_cache_slot works? >> >> I think adding the property_offset in op_array is kinda like a >> workaround for POC, and I want to remove it from op_array. >> >> >> Cheers, Yo-An >> >> >> Xinchen Hui =E6=96=BC 2016=E5=B9=B44=E6=9C=881=E6=97= =A5 =E6=98=9F=E6=9C=9F=E4=BA=94=E5=AF=AB=E9=81=93=EF=BC=9A >> >> Hey: >>> >>> On Fri, Apr 1, 2016 at 4:35 PM, Lin Yo-An >>> wrote: >>> >>>> Hi Dmitry, Nikita, Andrea >>>> >>>> >>>> My implementation now is able to get the property offset and fetch >>>> object property directly without invoking zend_std_read_property and >>>> pushing new call frame onto the stack. >>>> >>>> The current behavior: >>>> >>>> 1. In compile-time, the pass_two() function now marks the getter >>>> functions in op_array.accessor.type >>>> >>>> 2. When Zend Engine first time attempt to read the property, it saves >>>> the property offset in the accessor field and mark the method as a "ge= tter". >>>> >>> I am not sure if I understand you correctly, but.. have you consider >>> this case? >>> >>> >> class A { >>> private $a =3D 1; >>> private $b =3D 2; >>> public function __get($name) { >>> static $is_first =3D 1; >>> if ($is_first) { >>> $is_first =3D 0; >>> return $this->a; >>> } else { >>> return $this->b; >>> } >>> } >>> } >>> >>> >>> $a =3D new A(); >>> echo $a->nomeaning; >>> echo $a->nomeaning; >>> ?> >>> >>> thanks >>> >>>> >>>> 3. When Zend Engine second time invoke the getter method, it checks th= e >>>> accessor field and try to read the property value directly instead a >>>> "method call" >>>> >>>> >>>> >>>> The implementation did some change: >>>> >>>> 1. Added accessor struct to op_array to save "accessor" related >>>> information (getter or setter, property offset) >>>> >>>> 2. Added two statement in zend_std_read_property to save property >>>> offset. >>>> >>>> 3. Added op code check in zend_compile (The pass_two() function) to >>>> mark a function is a getter) >>>> >>>> >>>> But now I encountered a problem, I can't store the result value in >>>> INIT_METHOD_CALL op, the result var is only available in DO_FCALL_* >>>> >>>> >>>> >>>> I have an idea for solving this, but I'm not sure if it's good or not: >>>> >>>> >>>> If DO_FCALL_* will always follow a INIT_METHOD_CALL, then I think we >>>> can store result var from the next op (DO_FCALL) and skip DO_FCALL dir= ectly. >>>> >>>> >>>> Would be great if I can have your advices and suggestion. :-) >>>> >>>> >>>> Thanks, Yo-An Lin >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> On Tue, Mar 22, 2016 at 4:45 PM, Dmitry Stogov wrote= : >>>> >>>>> Hi Yo-An Lin, >>>>> >>>>> >>>>> This "run-time inlining" approach may work. >>>>> >>>>> >>>>> PHP compiler (or optimizer) may mark functions and methods suitable >>>>> for "run-time" inlining (e.g. methods without arguments and FETCH_OBJ= _R >>>>> UNUSED, CONST -> TMP; RETURN TMP). >>>>> >>>>> Then INIT_METHOD_CALL may check this flag and execute "optimized code >>>>> sequence" instead of pushing stack frame and real call. >>>>> >>>>> >>>>> However, I'm not sure what kind of performance impact this may make, >>>>> because we will have to make additional check on each INIT_METHOD_CAL= L >>>>> execution. >>>>> >>>>> >>>>> Thanks. Dmitry. >>>>> >>>>> >>>>> ------------------------------ >>>>> *From:* Lin Yo-An >>>>> *Sent:* Saturday, March 19, 2016 10:08 >>>>> *To:* Dmitry Stogov >>>>> *Cc:* internals; Xinchen Hui >>>>> *Subject:* Re: [PHP-DEV] Object getter method optimization >>>>> >>>>> Hi Dmitry, >>>>> >>>>> >>>>> Thanks for your reply! You're correct. let me try to explain your >>>>> points: >>>>> >>>>> If I have a main.php and worker.php >>>>> >>>>> And I defined work($worker) { $status =3D $worker->getStatus(); } ins= ide >>>>> main.php >>>>> >>>>> when main.php is compiled, we don't know what the class entry of >>>>> $worker is. What we only know is invoking a method "getStatus" on $wo= rker >>>>> CV unless we know we have to compile worker.php before main.php and a= dd a >>>>> type hint on $worker. >>>>> >>>>> Is it correct? >>>>> >>>>> >>>>> Since the original approach doesn't work, here comes another new idea= : >>>>> >>>>> When executing method call on an object, if we found the method body >>>>> are just 2 op codes (FETCH_OBJ_R and RETURN), we then denote the meth= od is >>>>> a "getter method" >>>>> >>>>> And the next time, when we execute the same method, we found the >>>>> "getter method" flag, we simply execute FETCH_OBJ_R on that object an= d >>>>> return the value to avoid extra op code execution time. >>>>> >>>>> Do you think if this could work? >>>>> >>>>> >>>>> >>>>> >>>>> Best Regards and Thanks for your work on PHP VM >>>>> Yo-An Lin >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> On Fri, Mar 18, 2016 at 3:36 PM, Dmitry Stogov >>>>> wrote: >>>>> >>>>>> Hi Yo-An Lin, >>>>>> >>>>>> Unfortunately, this approach won't work. >>>>>> At first, at compile time we don't know the body of called getter. >>>>>> At second, the called method might be changed even at run-time, >>>>>> because of polymorphism. >>>>>> >>>>>> Tricks like this might be implemented using JIT and polymorphic >>>>>> inline caches. >>>>>> >>>>>> Thanks. Dmitry. >>>>>> >>>>>> ________________________________________ >>>>>> From: Lin Yo-An >>>>>> Sent: Friday, March 18, 2016 05:23 >>>>>> To: internals >>>>>> Subject: [PHP-DEV] Object getter method optimization >>>>>> >>>>>> Hello Everyone, >>>>>> >>>>>> >>>>>> I am recently trying to write an optimizer that could optimize the >>>>>> getter >>>>>> method call into just one object fetch opcode. >>>>>> >>>>>> I'd like to know thoughts from you guys, here is the note: >>>>>> https://c9s.hackpad.com/INLINE-OP-TVGo9WcshbZ >>>>>> >>>>>> -- >>>>>> Best Regards, >>>>>> >>>>>> Yo-An Lin >>>>>> https://github.com/c9s >>>>>> >>>>> >>>>> >>>>> >>>>> -- >>>>> Best Regards, >>>>> >>>>> Yo-An Lin >>>>> >>>> >>>> >>>> >>>> -- >>>> Best Regards, >>>> >>>> Yo-An Lin >>>> >>> >>> >>> >>> -- >>> Xinchen Hui >>> @Laruence >>> http://www.laruence.com/ >>> >> >> >> -- >> Sent from Gmail Mobile >> > > > > -- > Best Regards, > > Yo-An Lin > --=20 Best Regards, Yo-An Lin --089e0158a8366fdb4e052fbd4577--