[Ecls-list] ECL behavior on some array related code

Juan Jose Garcia-Ripoll juanjose.garciaripoll at googlemail.com
Wed May 19 13:31:41 UTC 2010


Some news about the compiler... But before I write about them let me explain
that this is not yet uploaded to git/CVS due to firewall problems

I have implemented various simplifications. Just in case anyone care, they
are the following ones.

First, improved the accuracy with which variables keep track of the forms in
which they are read or assigned values. This is essential for substituting
variables with their values, thus simplifying (LET ((X 2)) (COS X)) into
(COS 2).

Second, when replacing a variable with its value, ECL used to create a kind
of proxy. The translation would be (COS (VALUES 2)) instead of (COS 2).
Since we have no type propagation algorithm activated, this meant that COS
did not know the actual type of the argument and it would not get optimized.

Third, array operations are now optimized using compiler macros. These
macros produce code which may or may not contain safety checks (ensure it
has an array, right rank, right index bounds), but always result into a
simple call to ROW-MAJOR-AREF/ASET, a function that can be efficiently
inlined if the types are known.

Fourth, LET/LET* forms now incorporate a bit more accurate phases for
replacing variables with their values, determining the variable types before
processing the LET body, etc.

Fifth, I have compiled a database with the intermediate language that ECL
uses for compilation, describing their side effects, whether forms can be
moved or not, etc.

Sixth, DOTIMES now declares the type of the variable if the number of times
is known in advance.

Using all this the compiler can indeed produce much better code, even though
it still lacks good type inference. As an example, in the Spartans test
suite there is a test that I rewrote for efficiency as follows

(defun run-array-set ()
  (declare (optimize (speed 3) (debug 0) (safety 0)))
  (flet ((xloop ()
        (let ((A (make-array '(100 100 100) :element-type 'single-float
                 :adjustable nil))
          (value 8.5))
          (dotimes (n 50)
        (dotimes (i 90)
          (dotimes (j 90)
            (dotimes (k 90)
              (setf (aref A i j k) value))))))))
    (time (funcall #'xloop))))

These are the results of running the test:

SBCL:
Evaluation took:
  0.061 seconds of real time
  0.061434 seconds of total run time (0.059799 user, 0.001635 system)
  100.00% CPU
  187,758,281 processor cycles
  4,004,112 bytes consed

ECL(git/CVS):
real time : 0.079 secs
run time  : 0.075 secs
gc count  : 2 times
consed    : 4000177 bytes

And here is the code it generates:

static cl_object L1c__gazonk()
{ VT2 VLEX2 CLSR2 STCK2
    const cl_env_ptr cl_env_copy = ecl_process_env();
    cl_object value0;
TTL:
    {cl_object V1;                            /*  A               */
    V1=
si_make_pure_array(ECL_SYM("SINGLE-FLOAT",776),VV[0],Cnil,Cnil,Cnil,MAKE_FIXNUM(0))
/*  MAKE-PURE-ARRAY */;
    {int8_t V2;                               /*  N               */
    V2= ((int8_t)0);
    goto L5;
L4:;
    {int8_t V3;                               /*  I               */
    V3= ((int8_t)0);
    goto L11;
L10:;
    {int8_t V4;                               /*  J               */
    V4= ((int8_t)0);
    goto L17;
L16:;
    {int8_t V5;                               /*  K               */
    V5= ((int8_t)0);
    goto L23;
L22:;
    {cl_fixnum V6;
    {cl_fixnum V7;
    cl_fixnum V8;
    cl_fixnum V9;
    V7= ((cl_fixnum)V3);
    V8= V7;
    V9= 0;
    V9= (V1)->array.dims[0];
    V8= (V8)*(V9);
    V9= (V1)->array.dims[1];
    V7= ((cl_fixnum)V4);
    V8= (V8)+(V7);
    V8= (V8)*(V9);
    V9= (V1)->array.dims[2];
    V7= ((cl_fixnum)V5);
    V8= (V8)+(V7);
    V6= V8;
    }
    (V1)->array.self.sf[V6]=    8.5    ;}
    V5= ((int8_t)(((cl_fixnum)V5))+1);
L23:;
    if(!((((cl_fixnum)V5))<(90))){
    goto L54;}
    goto L22;
L54:;
    goto L52;
L52:;
    goto L19;
    }
L19:;
    V4= ((int8_t)(((cl_fixnum)V4))+1);
L17:;
    if(!((((cl_fixnum)V4))<(90))){
    goto L60;}
    goto L16;
L60:;
    goto L58;
L58:;
    goto L13;
    }
L13:;
    V3= ((int8_t)(((cl_fixnum)V3))+1);
L11:;
    if(!((((cl_fixnum)V3))<(90))){
    goto L66;}
    goto L10;
L66:;
    goto L64;
L64:;
    goto L7;
    }
L7:;
    V2= ((int8_t)(((cl_fixnum)V2))+1);
L5:;
    if(!((((cl_fixnum)V2))<(50))){
    goto L72;}
    goto L4;
L72:;
    goto L70;
L70:;
    value0=Cnil; cl_env_copy->nvalues=1;
    return value0;
    }
    }
}

-- 
Instituto de Física Fundamental, CSIC
c/ Serrano, 113b, Madrid 28006 (Spain)
http://tream.dreamhosters.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/ecl-devel/attachments/20100519/5471248c/attachment.html>


More information about the ecl-devel mailing list