develooper Front page | perl.cvs.parrot | Postings from December 2008

[svn:parrot] r33844 - trunk/docs/book

December 12, 2008 18:14
[svn:parrot] r33844 - trunk/docs/book
Message ID:
Author: Whiteknight
Date: Fri Dec 12 18:14:08 2008
New Revision: 33844


[Book] Add more information about the CGP core, and some small fixes about the CG core.

Modified: trunk/docs/book/ch12_opcodes.pod
--- trunk/docs/book/ch12_opcodes.pod	(original)
+++ trunk/docs/book/ch12_opcodes.pod	Fri Dec 12 18:14:08 2008
@@ -127,7 +127,7 @@
 C<void **> values. In the computed goto core, all the labels represent
 different opcodes, so they are stored in an array:
-  void **my_labels[] = {
+  void *my_labels[] = {
@@ -142,29 +142,60 @@
 Jumping to one of these labels is done with a command like this:
-  goto my_labels[opcode_number];
+  goto *my_labels[opcode_number];
 Actually, opcodes are pointed to by an C<opcode_t *> pointer, and all
 opcodes are stored sequentially in memory, so the actual jump in the
 computed goto core must increment the pointer and then jump to the new
 version. In C it looks something like this:
-  goto my_labels[*(current_opcode += 1)];
+  goto *my_labels[*(current_opcode += 1)];
-Each opcode is a label, and at the end of each opcode an instruction like
-this is performed to move to the next opcode in series, or else some
-kind of control flow occurs that moves it to a non-sequential location:
+Each opcode is an index into the array of labels, and at the end of each
+opcode an instruction like this is performed to move to the next opcode
+in series, or else some kind of control flow occurs that moves it to a
+non-sequential location:
-  goto my_lables[*(current_opcode = destination)];
+  goto *my_lables[*(current_opcode = destination)];
 These are simplifications on what really happens in this core, because
 the actual code has been optimized quite a bit from what has been
-presented here. 
+presented here. However, as we shall see with the precomputed goto core,
+it isn't optimized as aggressively as is possible.
 =item* Precomputed Goto Core
-Thought the Computed Goto core was hard enough to understand? Precomputed
-goto takes the concept a little further.
+The precomputed goto core is an amazingly optimized fast core that uses
+the same computed goto feature, but performs the array dereferencing
+before the core even starts. In the computed goto core, you have this
+operation to move to the next opcode:
+  goto *my_labels[*(current_opcode += 1)];
+This single line of code is deceptively complex. A number of machine code
+operations must be performed to complete this step: The value of
+C<current_opcode> must be incremented to the next value, that value must
+be dereferenced to find the opcode value. In C, arrays are pointers, so
+C<my_labels> gets dereferenced and an offset is taken according to find
+the stored label reference. That label reference is then dereferenced, and
+the jump is performed.
+That's a lot of steps to execute before we can jump to the next opcode.
+Now, what, if each opcode value was replaced with the value of the jump
+label beforehand? If C<current_opcode> points to a label referenced
+already, we don't need the array at all. We can replace that entire mess
+above with this line:
+  goto **(current_opcode += 1);
+That's far fewer machine instructions to execute before we can move to the
+next opcode, which means faster throughput. Remember that whatever dispatch
+mechanism is used will be called after every singly opcode, and some large
+programs may have millions of opcodes! Every single machine instruction
+that can be cut out of the dispatch mechanism could increase the execution
+speed of Parrot in a significant and noticable way. The precomputed goto
+core, while not available on all compilers, takes the idea of optimization
+to the extreme.
 =item* Tracing Core Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About