[gambit-list] newbie: bitwise and arithmetic runtime speed for u64

Marc Feeley feeley at iro.umontreal.ca
Sun Apr 26 18:20:56 EDT 2020


Marc



> On Apr 26, 2020, at 9:48 AM, Paolo <pmontrasi at gmail.com> wrote:
> 
> Hi Brad, thank you for your suggestion.
> I ended up in testing something similar to the following example
> 
> (define (u64-xor . args-list)
>   (##bignum.normalize! 
>     (fold
>       (lambda (x big) 
>         (let ((x-big (if (fixnum? x) (##fixnum->bignum x) x)))
>           (##bignum.adigit-bitwise-xor! big 0 x-big 0)
>           big))
>       (##bignum.make 2 ##bignum.adigit-zeros #f)
>       args-list)))
> 
> it worked but with no noticeable improvements and this fact helped me in looking elsewhere to find speed problems … I found a lot of them in my code of course ;-)
> 
> Well I tried to do my best to fix most of the performance issues and I am now pretty happy with what I have come to, therefore I point you to my code in case you are looking for a fun "chess scheme" challenge.
> 
> https://github.com/pmon/coronachess
> 
> Thank you for your help, my best
> Paolo

Nice!  I’ll have to try it out… As you noticed the name Gambit has its origins in chess… I used to play regularly.  A gambit is a kind of scheme… and it is a calculated risk (which felt quite appropriate for my PhD work which was also risky).

To do high speed calculations on raw 64 bit integers, I would tend to use u64vectors (or even u8vectors) to store the 64 bit integers and to drop down to C when some operation on these integers must be done without creating bignums.  Something along these lines:

(declare
  (standard-bindings)
  (extended-bindings)
  (not safe)
)

(c-declare "#define ELEM0(u64vect) ___BODY_AS(u64vect,___tSUBTYPED)[0]")

(define-macro (u64-xor! v1 v2) ;; v1[0] = v1[0] ^ v2[0]
  `(##c-code "ELEM0(___ARG1) ^= ELEM0(___ARG2);" v1 v2))

(define v1 (u64vector #x0123456789ABCDEF))
(define v2 (u64vector #x00FF00FF00FF00FF))

(println (number->string (u64vector-ref v1 0) 16))
(println (number->string (u64vector-ref v2 0) 16))

(u64-xor! v1 v2)

(println (number->string (u64vector-ref v1 0) 16))

You could create a small library of such macros for the various 64 bit operations, and try to avoid as much as possible conversions to and from bignums which probably incurs a high overhead in your application.

Marc





More information about the Gambit-list mailing list