📜 ⬆️ ⬇️

Simple test llvm / libjit part III, now also parrot

This article is a continuation of the articles:
Simple test libjit vs llvm
A simple llvm / libjit part II test, the same + gnu lightning .

Introductory curtsy



In previous articles, the performance of llvm, libjit and gnu lightning was examined using the example of the sieve of eratosthenes. All of the options considered are low-level libraries that have a good rate of fire, but are essentially specialized assemblers, and, for example, you will have to implement work with strings yourself.
')
There are other virtual machines that you can include in your program as a backend for your DSL . For example - born as a result of April Fool's joke - parrot is the basis of the future pearl.

There, the possibilities are much greater, including strings, hash tables, dimensionless arrays, garbage collection, console and file I / O, and other nice things. The question is - what is the price (in performance loss) for all these nice additions?

Let's try.

Eratosthene sieve on parrot


As before - these are two procedures, one of them (erato) is implemented by the algorithm itself, the second (main) runs 100_000 times erato to search for prime numbers from 1 to 50_000.

.loadlib 'trans_ops'
.loadlib 'math_ops'

.sub 'erato'
.param int n
$P0 = new 'ResizableIntegerArray' # a = P0
$P0 = n
$N0 = sqrt n # q = I0
$I0 = floor $N0 # i = I1
$I1 = 2
for_cond:
if $I1 > $I0 goto for_end
$I2 = $P0[$I1]
if $I2 == 1 goto end_if
$I3 = $I1 * $I1 # j = I3
while_cond:
if $I3 > n goto while_end
$P0[$I3] = 1
$I3 += $I1
goto while_cond
while_end:
end_if:
$I1 += 1
goto for_cond
for_end:
.end

.sub main :main
$I10 = 0
for_test1:
if $I0>100000 goto for_end1
erato(50000)
$I0 += 1
goto for_test1
for_end1:
.end



And - a control program that runs all this:

001 : #include <parrot/embed.h>
002: #include <parrot/extend.h>
003:

004: int main ( int argc, char * argv[])
005: {
006: Parrot_Interp interp;
007: Parrot_PackFile pf;
008:
009: interp = Parrot_new( NULL );
010: if ( ! interp) {
011: return 1 ;
012: }
013:
014: pf = Parrot_pbc_read(interp, "erato.pbc" , 0 );
015: Parrot_pbc_load(interp, pf);
016: Parrot_runcode(interp, argc, argv);
017:
018: Parrot_destroy(interp);
019:
020: return 0 ;
021: }
022:


So, compile a new version:
parrot -o erato.pbc erato.ptr
gcc -O2 erato.c -I /usr/include/parrot/2.0.0/ -lparrot -o erato

And launch:
/usr/bin/time -f "%U" ./erato
2361.2

Products and fruits of the author's movement of thought


Total, our table takes the form:

VMRuntime in seconds, (less = better)
Llvm13.77
LIBJIT14.17
GNU LIGHTNING32.59
PARROT2361
And just for information:
gcc -O050.09
gcc -O113.79
similar perl program4288


That is, the parrot virtual machine runs on our example 150 times slower than the jit of the machine. But 2 times faster than the program on the pearl. This is actually good news, it looks like the following versions of the pearl, based on parrot, are going to work faster than today ... However, parrot is clearly not a replacement for the other machines considered if speed is needed.

Final chord



In general, parrot left a very pleasant impression, everything works as described, there were no pitfalls, opportunities — the sea, and the documentation is good. Write on it after llvm - a pleasure. So for myself, I made up the following recommendations:

Source: https://habr.com/ru/post/102533/


All Articles