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

Paolo pmontrasi at gmail.com
Fri May 1 09:13:10 EDT 2020


Thanks Marc, I see the point in bignums conversion and I am trying your suggested approach.
Mostly I have u64vectors with multiple elements to use in the bitwise operation and being able to reference / use one of the arbitrary elements in the vector could avoid in converting to/from bignums using u64vector-ref / u64-vector-set! , if I understood your point.

I tried the following code but it is not working

(c-declare "#define ELEM_N(u64vect,index) ___BODY_AS(u64vect,___tSUBTYPED)[index]")

(define-macro (u64-xor! v1 i1 v2 i2)
 `(##c-code "ELEM_N(___ARG1,___ARG2) ^= ELEM_N(___ARG3,___ARG4);" ,v1 ,i1 ,v2 ,i2))

running

(define u64one-bits (u64vector 1))
(define v7 (make-u64vector 10 0))
(pretty-print v7)
(u64-xor! v7 0 u64one-bits 0)
(u64-xor! v7 1 u64one-bits 0) ; trying to use the second element with index 1
(pretty-print v7)

I get the following

#u64(0 0 0 0 0 0 0 0 0 0)
#u64(1 0 0 0 1 0 0 0 0 0)

… of course that was an easy but incorrect guess ;-)
Is there a way to declare a macro that gets the index of the vector as parameter?

Thanks
Paolo

> Il giorno 27 apr 2020, alle ore 00:20, Marc Feeley <feeley at iro.umontreal.ca> ha scritto:
> 
> 
> 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

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.iro.umontreal.ca/pipermail/gambit-list/attachments/20200501/0aecf237/attachment.htm>


More information about the Gambit-list mailing list