Setting up PHP build environment on Windows

One of the things I have done many times in the past year is setting up a build environment for PHP on Windows. I have been using a simple script to do this which I am releasing today with this blog. Here is the zip file contains the script winbuild.bat along with essential tools (wget and unzip) which the script requires. Before you run winbuild.bat, make sure Visual Studio (or VC9 expression edition) and TortoiseSVN are installed on the machine. If you do not have these already installed, you can install VC9 express edition from http://www.microsoft.com/express/downloads/ (select visual studio 2008 express) and TortoiseSVN from http://tortoisesvn.net/downloads. Installation of TortoiseSVN might require a reboot. Once machine is ready, download the attached zip, unzip files in a folder, say c:\winbuild, launch visual studio command prompt and then run c:\winbuild\winbuild.bat. By default this script will setup PHP 5.3 build environment in %systemdrive%\php\php_sdk\php_53_dev folder. If you want to choose a different branch and folder location, open winbuild.bat, change variable values on top of the script before running it. This script does the following for setting up the build environment.
 
·         Create folder structure recommended here.
·         Download and unzip binary tools package.
·         Download and unzip all dependency libraries.
·         Download php source code from http://svn.php.net.
·         Run buildconf and configure commands.
 
After the script is complete, PHP root will be set to c:\php\php_sdk\php_53_dev\vc9\x86\PHP_5_3. If you change branch/folder locations in the script, this will be different. With the build environment set, you can now run “nmake snap” to build PHP in the PHP root folder. If you want to change configure options, open config.nice.bat (present in PHP root), change the options and run it. Running “nmake snap” will now build PHP using new configure options. Once the build is complete, release binaries will be under the release folder under php root.
 
Hope this makes setting PHP build environment much simpler. If you run into a bug in winbuild.bat, let me know by leaving a comment. Feature suggestions are also welcome.

Download script here.
 

Thanks.
Kanwal

Goodness of dynamic maxInstances in FastCGI

One of the major pain points in FastCGI 1.0 was that users were required to set maxInstances to a number which works best for their application. Many users didn’t tune this value and were running FastCGI with default value of maxInstances which didn’t give them optimal performance. We recommended users to set maxInstances to (10 * number of processors) if they don’t want to go through the pain of finding the ideal maxInstances for them which worked much better than default value but still didn’t give optimal performance. Even when users fine-tuned maxInstances to ideal value, they didn’t always get best possible performance at all times due to variations in traffic, server/application configuration changes and code changes.
 
In IIS 7.5 we fixed this pain point by making FastCGI module capable of monitoring system state and adjust this number dynamically to give best possible performance. This feature is referred to as dynamic maxInstances or auto maxInstances and can be enabled by setting maxInstances value to 0. As we intend to maintain a consistent platform for PHP developers on WinXP and above, we have added this feature to FastCGI ISAPI 1.5 and made it available on IIS 7.0 as well (read more here). Last week I spent some time comparing dynamic maxInstances results with suggested maxInstances value (10 * processor count) results and below is what I got.
 
Hardware: Quad core machine with 4 GB RAM
Application: Joomla
 

 

 
MaxInstances = 40
MaxInstances = 0
%age difference
Path Length (less is good)
154177
142294
7.66%
Response Time (less is good)
844 ms
783 ms
7.22%
Context switches/sec (less is good)
171.76
79.69
-53.60%
Requests/Sec (more is good)
59.06
63.76
7.95%
 
As you can see, all performance parameters improved considerably just by changing maxInstances to 0. Our testing showed similar improvements in performance of other PHP applications as well. So we changed the default value of maxInstances to 0 in FastCGI ISAPI 1.5 and Win7. Note that if a value is explicitly set in fcgiext.ini or applicationHost.config, that value will override default value. Due to restrictions of QFE release process, we couldn’t change the default of maxInstances in IIS 7.0. So you are required to enable dynamic maxInstances after install this update on IIS 7.0.
 
We typically run many applications on our performance bench machines and were required to choose one maxInstances number for all applications. Choosing a different maxInstances number for each application was a better way to do performance testing but that was painful. Now with dynamic maxInstances, we get optimal performance for each application without any pain. Our performance testing is loving this feature and I hope you love it too.
 
Thanks.
Kanwal

What’s new in WinCache 1.1 Beta2 and what’s next

After WinCache 1.0 release, two most requested features were user cache and session cache. We added both of these features in WinCache 1.1 beta1. We are very happy with the rate of adoption of user cache by PHP application developers. Many application developers have already added support for WinCache user cache in their applications and many are in the process of adding it. Earlier we were planning to add only these two features in WinCache 1.1 and then do more performance optimizations in WinCache 1.2 but later we decided to add these additional optimizations in 1.1 release itself. Because of this, we did beta2 release which has file change notification and function hooks support along with some small feature additions. Below is the full list of features which got added to WinCache 1.1 up to beta2 release.
 
1.       User cache APIs – We have added APIs like wincache_ucache_get, wincache_ucache_set etc. (see full list here) which can be used to store and retrieve application data from the cache. Since the cache is shared among all PHP processes under an application pool, application developers can calculate data once, store it in the cache and then retrieve it in next request instead of calculating it every time. Database query results, site counters etc. are good candidates to be stored in user cache. These APIs behave much like user cache APIs available in APC to make it easier for developers to use existing code written for APC.
 
2.       WinCache session handler – PHP provides three session handlers (files, shm, user) out of the box of which shared memory (shm) handler doesn’t work on windows. Session handler “files” is the most commonly used session handler on windows which is slow as it requires file read on every request. We have implemented a session handler in WinCache which keeps session data in shared memory which is much faster compared to files. Since session data is expected to survive PHP and IIS process recycles, data is persisted on disk by WinCache in the folder specified by session.save_path. Since session.save_path is not a system level configuration, WinCache creates a separate session cache for different values of session.save_path. WinCache 1.1 stored this data in memory allocated for user cache but WinCache beta2 allocates separate memory for session cache.
 
3.       File change notification – WinCache now registers for change notifications to all folders under which a file is requested by file cache or opcode cache. When a file change notification is received, that file is removed from all the caches immediately. Doing this without incurring performance penalty required us to make all processes not listen to all the folders. So we designed a distributed change notification infrastructure which works without any master. Of all PHP processes running on the system for an application pool, only one of them listens to one folder. Other processes detects that a listener is present for the folder and do nothing. If a process dies, another process detects this situation and registers for a change listener itself. We made sure that no change is ever missed by this system and this system can easily scale to 100s of folders.
 
4.       Function hooks – With file cache and file change notification infrastructure in place, we decided to rewrite some PHP APIs like file_get_contents, is_file etc on top of this infrastructure to make them faster. For this we have added ability to define function hooks in WinCache.  WinCache 1.1 beta2 include this infrastructure but doesn’t include any function hooks. I am in the process of rewriting some functions and we will enable these hooks in WinCache 1.1 RC release.
 
5.       In WinCache 1.0, we create separate cache for PHP processes running under one process. This didn’t work too well in web garden scenarios. WinCache 1.1 has solved this problem by sharing cache for all PHP processes running under worker processes belonging to one application pool. If application pool id is not available (as in Apache), it will switch to old behavior.
 
6.       Added optional boolean argument summaryonly to all WinCache info functions. Ruslan requested this feature so that wincache_ocache_fileinfo function calls made by his wordpress widget on his site (http://ruslany.net) are faster. And based on customer feedback we changed wincache_ucache_info to accept an optional key to make it return information on just one user cache entry and exposed user cache entry size in each entry.
 
7.       Drupal application developers requested us to add wincache_lock, wincache_unlock APIs and we have added these in 1.1 Beta2 release. By default lock created by wincache_lock is scoped to all PHP processes sharing the cache. If you want a global lock, set optional argument isglobal to true.
 
8.       WinCache statistics page (wincache.php) has been changed to show user cache and session cache data and fixed bugs reported by customers on http://pecl.php.net/bugs/.
 
We are planning to add replacement APIs for PHP functions which deal with files in WinCache 1.1 RC release. We will also enable function hooks so that calls to PHP file APIs gets re-routed to these APIs. And as always, we will implement feature requests and fix bugs reported by you.
 
Thanks,
Kanwal