What is opcode
Perhaps you have tried to write dynamic content with C/s, although the development process is extremely cumbersome, but in order to achieve performance improvement, it may be worthwhile, they can compile dynamic content into binary executables, that is, the target code, by the operating system process directly loaded run. Today, very few people have used C + + to write dynamic content, the vast majority of Web developers enjoy the present happy time, a lot of good scripting language to choose from, such as Php,ruby,python, they are interpreted language, So the dynamic content written with them needs to be run by the interpreter program that relies on the response.
The interpreter program is also a binary executable, such as/bin/ruby, which can also run directly in the process, in which the interpreter needs to analyze the input script code, understand their purpose, and execute them. For example, we call PHP's interpreter and let it execute a simple script code:
~ zfs$ php-r ' Print 1+1; '
2
Well, it quickly outputs the right result, maybe you think the 1+1 is too small pediatrics, indeed, in the human brain computing 1+1 is very simple, almost do not think, but the interpreter does not work the way you think, 1+1 and 100+1000 for it is almost no difference, Because the interpreter core engine simply does not understand these scripting code and cannot execute directly, a series of code analysis work is required, and when the interpreter completes parsing the script code, it generates intermediate code that can be run directly, also known as the opcode (Operate code,opcode).
This process, from program code to intermediate code, is called an interpretation (parse), which is done by the interpreter. Similarly, compilers in compiled languages (such as compiler GCC in c) also generate intermediate code for program code, a process we call compilation (compile). One of the essential differences between compilers and interpreters is that the interpreter executes it directly after generating the intermediate code, so the runtime's control is in the interpreter, while the compiler further optimizes the intermediate code to produce a target program that can run directly, but does not execute it, and the user can execute it at any time thereafter. The control at this time is in the target program, and the compiler has nothing to do with it.
In fact, in terms of interpretation and compilation, their principles are similar, including lexical analysis, parsing, semantic analysis, and so on, sometimes the process of generating opcode in an interpreted language is also known as "compiling", which requires you to understand the context.
So, what exactly is opcode like? How does it explain what is generated? Let's take PHP as an example to find these answers.
The core engine of the PHP interpreter is Zend Engine, which can easily view its version:
~ zfs$ php-v
PHP 5.5.14 (CLI) (Built:sep 9 2014 19:09:25)
Copyright (c) 1997-2014 the PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies
Do you remember the script code we used to compute 1+1 in PHP before? Let's take a look at the opcode of this piece of code. Prior to this, you need to install the PHP parsekit extension, which is a binary extension written in C, maintained by PECL. With the parsekit extension, we can view any PHP file or code snippet opcode with the runtime API it provides. We call Parsekit_compile_string () directly on the command line, as follows:
/usr/local/php/bin/php-r "Var_dump (parsekit_compile_string (' Print 1+1; '));"
So we get the opcode of the code, and we return the array form, and the result is as follows:
Array (20) {
[' Type ']=>
Int (4)
["Type_name"]=>
String "Zend_eval_code"
["Fn_flags"]=>
Int (0)
["Num_args"]=>
Int (0)
["Required_num_args"]=>
Int (0)
["Pass_rest_by_reference"]=>
BOOL (FALSE)
["Uses_this"]=>
BOOL (FALSE)
["Line_start"]=>
Int (0)
["Line_end"]=>
Int (0)
["Return_reference"]=>
BOOL (FALSE)
["RefCount"]=>
Int (1)
["Last"]=>
Int (5)
[' Size ']=>
Int (5)
["T"]=>
Int (2)
["Last_brk_cont"]=>
Int (0)
["Current_brk_cont"]=>
Int (4294967295)
["Backpatch_count"]=>
Int (0)
["Done_pass_two"]=>
BOOL (TRUE)
["FileName"]=>
String (Parsekit Compiler)
["Opcodes"]=>
Array (5) {
[0]=>
Array (8) {
["Address"]=>
Int (33847532)
["OpCode"]=>
Int (1)
["Opcode_name"]=>
String (8) "Zend_add"
["Flags"]=>
Int (197378)
["Result"]=>
Array (3) {
[' Type ']=>
Int (2)
["Type_name"]=>
String (Ten) "Is_tmp_var"
["Var"]=>
Int (0)
}
["OP1"]=>
Array (3) {
[' Type ']=>
Int (1)
["Type_name"]=>
String (8) "Is_const"
["Constant"]=>
&int (1)
}
["OP2"]=>
Array (3) {
[' Type ']=>
Int (1)
["Type_name"]=>
String (8) "Is_const"
["Constant"]=>
&int (1)
}
["Lineno"]=>
Int (1)
}
[1]=>
Array (7) {
["Address"]=>
Int (33847652)
["OpCode"]=>
Int (41)
["Opcode_name"]=>
String (Ten) "Zend_print"
["Flags"]=>
Int (770)
["Result"]=>
Array (3) {
[' Type ']=>
Int (2)
["Type_name"]=>
String (Ten) "Is_tmp_var"
["Var"]=>
Int (1)
}
["OP1"]=>
Array (3) {
[' Type ']=>
Int (2)
["Type_name"]=>
String (Ten) "Is_tmp_var"
["Var"]=>
Int (0)
}
["Lineno"]=>
Int (1)
}
[2]=>
Array (7) {
["Address"]=>
Int (33847772)
["OpCode"]=>
Int (70)
["Opcode_name"]=>
String (9) "Zend_free"
["Flags"]=>
Int (271104)
["OP1"]=>
Array (4) {
[' Type ']=>
Int (2)
["Type_name"]=>
String (Ten) "Is_tmp_var"
["Var"]=>
Int (1)
["Ea.type"]=>
Int (0)
}
["OP2"]=>
Array (3) {
[' Type ']=>
Int (8)
["Type_name"]=>
String (9) "is_unused"
["Opline_num"]=>
String (1) "0"
}
["Lineno"]=>
Int (1)
}
[3]=>
Array (7) {
["Address"]=>
Int (33847892)
["OpCode"]=>
Int (62)
["Opcode_name"]=>
String (one) "Zend_return"
["Flags"]=>
Int (16777984)
["OP1"]=>
Array (3) {
[' Type ']=>
Int (1)
["Type_name"]=>
String (8) "Is_const"
["Constant"]=>
&null
}
["Extended_value"]=>
Int (0)
["Lineno"]=>
Int (1)
}
[4]=>
Array (5) {
["Address"]=>
Int (33848012)
["OpCode"]=>
Int (149)
["Opcode_name"]=>
String (zend_handle_exception)
["Flags"]=>
Int (0)
["Lineno"]=>
Int (1)
}
}
}
Installation of Parsekit extensions see this article
System cache
It means that the APC caches the compiled results of the PHP file source code, and then compares the time tag with each call. If it is not expired, it is run using the cached intermediate code. The default cache is 3600s (one hour). But it still wastes a lot of CPU time. Therefore, you can set the system cache to never expire (apc.ttl=0) in php.ini. However, if you do this, you need to restart the Web server after you change the PHP code. This type of caching is currently used more often.
User Data caching
Caching is read and written by the user when writing PHP code using the Apc_store and Apc_fetch function operations. If the amount of data is small, you can try. If the volume of data is large, it would be better to use a more monographs memory caching scheme similar to Memcache.
Installation of APC Module
The easiest way to do this is to use pecl directly and enter at the command line:/usr/local/php/bin/pecl Install APC
Then follow the prompts step-by-step, as shown in the following example:
[Root@iz23bm1tc0pz ~]#/usr/local/php/bin/pecl Install APC
Downloading apc-3.1.13.tgz ...
Starting to download apc-3.1.13.tgz (171,591 bytes)
... done:171,591 bytes-----------------------
source files, Building
Running:phpize
Configuring for:
PHP Api version:20100412
Zend Module Api no:20100525
Zend Extension Api no:220100525
Enable internal debugging in APC [No]: No
Enable per request file info about files used from the APC cache [No]: No
Enable Spin Locks (experimental) [No]: No
Enable memory Protection (experimental) [No]: No
Enable pthread mutexes (default) [No]: No
Enable pthread Read/write Locks (experimental) [Yes]: Yes
Then reboot the server:
LNMP nginx Restart
Let's take a look at the test results without using APC:
[Root@iz23bm1tc0pz ~]# ab-n1000-c100 http://zfsphp.cn/index.php
This is apachebench, Version 2.3 < $Revision: 1706008 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to the Apache Software Foundation, http://www.apache.org/
Benchmarking zfsphp.cn (Be patient)
Completed Requests
Completed Requests
Completed Requests
Completed Requests
Completed Requests
Completed Requests
Completed Requests
Completed Requests
Completed 900 Requests
Completed 1000 Requests
Finished 1000 requests
Server Software:nginx
Server Hostname:zfsphp.cn
Server port:80
Document Path:/index.php
Document length:14341 bytes
Concurrency level:100
Time taken for tests:15.517 seconds
Complete requests:1000
Failed requests:0
Total transferred:14544000 bytes
HTML transferred:14341000 bytes
Requests per second:64.45 [#/sec] (mean)
Time per request:1551.671 [MS] (mean)
Time/request:15.517 [MS] (mean, across all concurrent requests)
Transfer rate:915.34 [Kbytes/sec] Received
Connection Times (MS)
Min MEAN[+/-SD] Median max
Connect:0 2 4.8 0 17
processing:46 1481 277.0 1560 1638
Waiting:42 1481 277.1 1560 1638
total:58 1482 272.8 1560 1638
Percentage of the requests served within a certain time (MS)
50% 1560
66% 1576
75% 1582
80% 1587
90% 1602
95% 1612
98% 1622
99% 1629
100% 1638 (Longest request)
Visible maximum throughput rate is only 64.45reqs/s
Then we open the APC and the test results are as follows:
[Root@iz23bm1tc0pz ~]# ab-n1000-c100 http://zfsphp.cn/index.php
This is apachebench, Version 2.3 < $Revision: 1706008 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to the Apache Software Foundation, http://www.apache.org/
Benchmarking zfsphp.cn (Be patient)
Completed Requests
Completed Requests
Completed Requests
Completed Requests
Completed Requests
Completed Requests
Completed Requests
Completed Requests
Completed 900 Requests
Completed 1000 Requests
Finished 1000 requests
Server Software:nginx
Server Hostname:zfsphp.cn
Server port:80
Document Path:/index.php
Document length:14341 bytes
Concurrency level:100
Time taken for tests:7.122 seconds
Complete requests:1000
Failed requests:0
Total transferred:14544000 bytes
HTML transferred:14341000 bytes
Requests per second:140.41 [#/sec] (mean)
Time per request:712.189 [MS] (mean)
Time/request:7.122 [MS] (mean, across all concurrent requests)
Transfer rate:1994.29 [Kbytes/sec] Received
Connection Times (MS)
Min MEAN[+/-SD] Median max
Connect:0 1 2.4 0 10
Processing:23 677 125.3 705 775
Waiting:22 677 125.4 705 775
Total:30 678 123.1 705 775
Percentage of the requests served within a certain time (MS)
50% 705
66% 719
75% 726
80% 730
90% 742
95% 750
98% 760
99% 765
100% 775 (Longest request)
Visible throughput rate increased by more than one times, to reach 140.41reqs/s.
Then, we open the dynamic content cache (the landlord's blog with the Smarty cache), the test results are as follows:
[Root@iz23bm1tc0pz ~]# ab-n1000-c100 http://zfsphp.cn/index.php
This is apachebench, Version 2.3 < $Revision: 1706008 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to the Apache Software Foundation, http://www.apache.org/
Benchmarking zfsphp.cn (Be patient)
Completed Requests
Completed Requests
Completed Requests
Completed Requests
Completed Requests
Completed Requests
Completed Requests
Completed Requests
Completed 900 Requests
Completed 1000 Requests
Finished 1000 requests
Server Software:nginx
Server Hostname:zfsphp.cn
Server port:80
Document Path:/index.php
Document length:14341 bytes
Concurrency level:100
Time taken for tests:2.263 seconds
Complete requests:1000
Failed requests:0
Total transferred:14544000 bytes
HTML transferred:14341000 bytes
Requests per second:441.98 [#/sec] (mean)
Time per request:226.255 [MS] (mean)
Time/request:2.263 [MS] (mean, across all concurrent requests)
Transfer rate:6277.49 [Kbytes/sec] Received
Connection Times (MS)
Min MEAN[+/-SD] Median max
Connect:0 1 3.1 0 12
Processing:18 215 38.1 222 255
Waiting:18 215 38.3 222 255
Total:26 216 35.6 223 255
Percentage of the requests served within a certain time (MS)
50% 223
66% 230
75% 232
80% 234
90% 237
95% 239
98% 240
99% 243
100% 255 (Longest request)
This time throughput unexpectedly reached 441.98reqs/s, increased by more than three times times, compared to the original 64.45REQS/S improved nearly 7 times times, can be seen using APC opcode cache with Smarty cache, the optimization of the performance of the site is quite obvious.