A simple llvm / libjit test part III, now also parrot

    This article is a continuation of the articles:
    Simple test libjit vs llvm
    Simple test llvm / libjit part II, 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 of an April Fools' joke - parrot - the basis of the future pearl.

    There are many more features, including strings, hash tables, dimensionless arrays, garbage collection, console and file I / O, and other nice things. Question - what is the price (in loss of performance) for all these nice additions?

    Let's try.

    Eratosthenes sieve on parrot


    As before, these are two procedures, one of them (erato) implements the algorithm itself, the second (main) starts erato 100_000 times to search for primes from 1 to 50_000. And - a control program that starts it all: So, compilation of a new version: And launch:

    .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





    001:  #include 
    002:  #include 
    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:  



    parrot -o erato.pbc erato.ptr
    gcc -O2 erato.c -I /usr/include/parrot/2.0.0/ -lparrot -o erato


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

    Products and fruits of the author’s thought movement


    Total, our table takes the form:

    VMExecution time 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 150 times slower in our example than the jit machines. But 2 times faster than the pearl program. This is actually good news, it seems that the next 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, the possibilities are sea, and the documentation is good. Writing on it after llvm is a pleasure. So for myself, I made about the following recommendations:

    • need speed - llvm or libjit, llvm is preferable (better infrastructure, more tools)
    • cramped conditions, such as low memory and disk space - gnu lightning;
    • if speed is not too important, but you need convenience, work with strings or complex structures - parrot

    Also popular now: