To introduce myself I am Ankit Asthana and I am the program manager for the backend C++ compiler. In my last two blogs I provided an introduction to what Profile Guided Optimization (PGO) is all about and a case study which illustrates how PGO is used to make SAP NetWeaver faster. In this blog I would like to present the story about how PGO is used make official Windows PHP binaries faster. Stephen Zarkos (Program Manager for Windows PHP) has been kind enough for providing the content for this blog.

After reading this blog you folks should be able to further understand and use this case study to introduce PGO for your applications. In addition to this, for experienced PHP users, this blog post should serve as an optimization opportunity to further optimize Windows PHP performance for their specific workloads. So let’s get started!

As most of you probably already know PHP is a server side scripting language designed for web development but also used as a general purpose programming language. PHP is heavily used today and it powers millions of websites and webservers. In addition to this PHP is also used to power a plethora of open source content management system (CMS) such as Joomla, WordPress and Drupal.

The effort to PGO’ize the Windows PHP binaries was led by Microsoft Open Source Technology (OSTC) group. OSTC’s primary goal is to work with open-source communities to help their software interoperate with or run better on Windows Server and Windows Azure. To be precise, this is not the only group at Microsoft that works with open source but amazingly these days is only one of many. A few examples of projects this group works on are PHP on Windows, Openstack with Hyper-V, CoApp (coapp.org) and the Linux Integration Services for Hyper-V and Azure.

Why Windows-PHP team used Profile Guided Optimization (PGO)?

Over the past several years, Microsoft and its partners have worked diligently with the PHP community to improve the experience PHP developers and users have on Windows Server and Windows Azure. As a result newer versions of PHP (i.e. PHP 5.4) for Windows include dramatic improvements that come from a deep collaboration between the PHP Core Maintainers and Microsoft. One factor attributing to a faster Windows PHP 5.4 and 5.5 is Profile Guided Optimization (PGO). The overall goal with this collaboration is to improve PHP on Windows and enable Windows specific capabilities in a way that provides PHP users the same (or better, if possible) capabilities that they see on other platforms.

After having tested the water with using PGO for Windows PHP 5.3, the team was finally able to incorporate PGO for Windows PHP 5.4. Performance is a primary goal for the Windows PHP team which served as the key reason behind PGO’izing the PHP binaries on Windows. PGO provided an important opportunity to optimize the performance of the PHP interpreter without changing any functional behavior.

What are the ‘key steps’ performed by the Windows PHP team for PGO’izing Windows PHP binaries?

Revisiting my previous blogs, there are essentially three steps required in PGO’izing an application (Instrument, Train and Optimize). Remember the ‘Instrument’ and ‘Optimize’ steps require an ‘LTCG:PGINSTRUMENT’ and ‘LTCG:PGOPTIMIZE‘ build respectively (for more information please take a look at my last blog post).

The steps to PGO’ize Windows PHP binaries are essentially in-line with PGO’izing any generic application and are as follows:

For those of you who would like to get some firsthand experience in doing this, creating an instrumented version of the Windows PHP binaries requires user to pass the additional ‘–enable-pgi‘ parameter to the PHP configure script. After running the configure script just rebuild with ‘nmake snap’. For more detailed instructions on how to set this up take a look at this blog post.

Collecting Training Data (i.e. the Train Phase)

This step can be as simple as setting up PHP with IIS or Apache with your PHP application and then accessing the application via a web-browser. A good training session should exercise workflows that your users will hit most often. The Windows PHP team currently trains by having a number of PHP applications preconfigured, for both IIS and Apache (on Windows) and then exercising these applications via requesting specific pages (usually several times for the most used pages) in order to get wide coverage. As of today, the Windows PHP team trains with every snapshot and release build of PHP binaries.

Snapshot builds can happen multiple times a day (depending on the number of commits on that particular day). Every snapshot for PHP 5.4, 5.5 and the Master branch is automated where the build automation goes through the process of creating the instrumented binary, setting up IIS and Apache, running through a series of applications to produce the training data, copying those back to the PHP build directory and then finally rebuilding the optimized PHP.

The end result of the training phase is the “*.pgc” files which are essentially training data files that contain all the information required by the ‘Optimize phase’. You need to copy these files back into your PHP build directory for the next phase of the build.

Building optimized Windows PHP binaries (i.e. the Optimize Phase)

A user can build an optimized version of PHP binaries following the simple steps listed below: a. Copy the *.pgc files back to your PHP build directory b. Run the command “nmake –clean-pgo” to clean your build directory (but not the .pgc files) c. Re-run the configure script, but remove the “–enable-pgi” parameter and instead add the “–with-pgo” parameter d. Run “nmake” and then “nmake snap” to build the final optimized PHP

This entire process can take several hours, depending upon the speed of your build machine. For best results (i.e higher build throughput and maximum PGO performance gains), use Visual Studio 2012 RTM.

What were the ‘key challenges’ faced by the Windows PHP team while PGO’izing Windows PHP binaries?

The work for PGO’izing PHP began as a proof of concept exercise. The Windows PHP team did some work several years ago to test PGO and see how they can leverage it for PHP. This exercise was useful in finding the following few key challenges which the team addressed when enabling PGO for PHP 5.4:

How to train the PHP binaries: At first it was difficult for the Windows PHP team to understand how best to train the PHP Windows binaries. In particular, ‘what training scenarios to run?’, ‘how long to train for?’ and ‘what kind of applications to train with?’

Absorbing longer build times: To save man hours, every part of the ‘Windows PHP PGO build process was automated. Adding PGO to the build process was a fairly easy exercise, but the main challenge here was to deal with the additional build times required. Given the Windows PHP has various builds (thread-safe, non-thread, and now x86 & x64 for PHP 5.5) to absorb the additional build times they needed to add more/faster build systems, and improve their build automation to support concurrent builds.

Additional quality assurance required: Validating the effectiveness of your PGO training scenario is essential and plays a major part in obtaining maximum performance gains. Good testing is still the key to the success of PGO in PHP. At the time PHP 5.4 was released the Windows PHP team had pretty good test automation and hence were able to identify issues where using PGO changed the behavior of PHP. These issues observed were then mitigated by the use of #pragma statements.

What are the performance gains received by the Windows PHP team by PGO’izing their binaries?

For testing PHP performance, applications such as Drupal, Mediawiki, WordPress and Joomla are deployed on IIS and Apache webservers. These applications are then stressed using load agents and various metrics such as transactions per second (TPS) are recorded and reported. To better demonstrate the performance improvements we can see with PGO, the ‘TPS’ for these applications with/without PGO’ized PHP binaries is listed in the table below:

As you can see some of these results are pretty impressive! A detailed summary of these results which includes some of the gritty details used to generate these results can be found here.

Wrap up

Although Profile Guided Optimization (PGO) is a complex technology, I hope this blog provides you further evidence on the usefulness of PGO and does a fair job in explaining how the Windows PHP team PGO’ized the Windows PHP binaries. In my future blogs I will go over how PGO works under the hood to provide the performance gains enjoyed by a plethora of products out there.

So stay tuned! Additionally, if you would like us to blog about some other PGO-related scenarios or are just curios and have a few more questions about PGO please feel free to reach out to me. I will do my best to answer them.

Join the conversation

Could you expand on "identify issues where using PGO changed the behavior of PHP." This sounds like PGO is buggy and makes me less likely to try and use it. I previously assumed that PGO was a mature technology and that using it will not change the behaviour of my application, was I wrong.

Also you say "These issues observed were then mitigated by the use of #pragma statements." What #pragma statements? Don't be a tease if there's something we need to know in order to use PGO please be specific.

@Motti, PGO is indeed a mature technology and PGO does not change the nature and the behavior of the application. The nature and behavior of the application remains the same, however as a result of PGO build more aggressive optimizations are run, this can surface 'source code' bugs not exposed with lower optimization levels in some cases.

You can use these to enable/disable some or all optimization for a particular function or set of functions. In PHP we used these to mitigate any issues we found. In our testing with PHP, disabling optimization for just a single problematic function did not measurably impact the overall performance gains.

For the first time I am able to get the name of a group working for OSS… Microsoft Open Source Technology (OSTC) group.

@Ankit Asthana, Since I don't know how to contact a member of that group for suggestions (perhaps a uservoice channel), would you please bring to their notice that some circles need their help very badly ! :)

For example, Vagrant (vagrantup.com) is a CLI based VM manager wrapper build in Ruby, most common in developers circle. It supports VirtualBox and VMware. Unfortunately, there is no support for Hyper-V github.com/…/1244. However, they provide an interface to implement any VM server software.

Similarly, there is a very limited support for native/offline OCR and in general Computer Vision in Windows RT (WOA) and Windows Phone. The only option is either use FastCV (developer.qualcomm.com/…/tools-and-resources), thanks for Qualcomm to care about Windows RT, or use cloud-based services (as opposed to native support).

Would be nice of you ask OSTC can help people:

– Implementing Hyper-V support for Vagrant. At least someone with Hyper-V CLI knowledge join the discussion (github.com/mitchellh/vagrant/issues/1244). We contacted IronRuby team, but the lead person has left Microsoft and the project is officially abandoned.