[gambit-list] Slow Bit Hacking with c-lambda

Bradley Lucier lucier at math.purdue.edu
Wed Nov 7 12:38:43 EST 2012


http://c2.com/cgi/wiki?PrematureOptimization

I rewrote your code to magnify the difference between inlined abs and
min and FFI abs and min.  I came up with this:

        ;; ffi-test.scm
        
        
        (declare (standard-bindings)
        	 (extended-bindings)
        	 (block)
        	 (fixnum)
        	 (not safe)
        	 ;; the following is not generally recommended
        	 (not interrupts-enabled))
        
        ;; INTEGER ABSOLUTE
        (define abs-integer
          (c-lambda (int) int
            "// we want to find the absolute value of arg1
             int const mask = ___arg1 >> sizeof(int) * CHAR_BIT - 1;
             ___result = (___arg1 + mask) ^ mask;"))
        
        
        (define min-integer
          (c-lambda (int int) int
            "// find the smaller of arg1 arg2
             ___result = ___arg2 ^ ((___arg1 ^ ___arg2) & -(___arg1 <
        ___arg2));"))
        
        (define N 10000000)
        
        (define (test-abs)
          (let ((result (time (let loop-i ((i 0)
        				   (result 0))
        			(if (fx< i N)
        			    (loop-i (fx+ i 1)
        				    (abs i))
        			    result)))))
            (time (let loop-j ((j 0)
        		       (result result))
        	    (if (fx< j N)
        		(loop-j (fx+ j 1)
        			(abs-integer j))
        		result)))))
        
        (define (test-min)
          (let ((result (time (let loop-i ((i 0)
        				   (result 0))
        			(if (fx< i N)
        			    (loop-i (fx+ i 1)
        				    (min result i))
        			    result)))))
            (time (let loop-j ((j 0)
        		       (result result))
        	    (if (fx< j N)
        		(loop-j (fx+ j 1)
        			(min-integer result j))
        		result)))))
        
        ;; run tests
        
        (test-abs)
        (test-min)
        
The result is

        heine:~/Downloads> gsc -keep-c  -cc-options '-save-temps'
        ffi-test
        heine:~/Downloads> gsi ffi-test
        (time (let loop-i ((i 0) (result 0)) (if (fx< i N) (loop-i (fx+
        i 1) (abs i)) result)))
            9 ms real time
            8 ms cpu time (8 user, 0 system)
            no collections
            no bytes allocated
            no minor faults
            no major faults
        (time (let loop-j ((j 0) (result result)) (if (fx< j N) (loop-j
        (fx+ j 1) (abs-integer j)) result)))
            357 ms real time
            356 ms cpu time (356 user, 0 system)
            no collections
            no bytes allocated
            no minor faults
            no major faults
        (time (let loop-i ((i 0) (result 0)) (if (fx< i N) (loop-i (fx+
        i 1) (min result i)) result)))
            15 ms real time
            16 ms cpu time (16 user, 0 system)
            no collections
            no bytes allocated
            no minor faults
            no major faults
        (time (let loop-j ((j 0) (result result)) (if (fx< j N) (loop-j
        (fx+ j 1) (min-integer result j)) result)))
            459 ms real time
            460 ms cpu time (460 user, 0 system)
            no collections
            no bytes allocated
            no minor faults
            no major faults
        
Search for ^ in ffi-test.i and ffi-test.c to see how your C code is
included in the generated C code.

So starting by worrying about how low-level features are implemented in
Gambit is totally the wrong way around.  Start by learning how to use
the options and declarations that Gambit offers.  I use Gambit all the
time for image processing, and I don't have any problems with speed.

Brad




More information about the Gambit-list mailing list