Re: SHA256 performance with Guile 2.2 vs. Guile 3.0

2020-01-03 Thread Ludovic Courtès
Ludovic Courtès  skribis:

> ludo@ribbon ~/src/guix$ ./pre-inst-env guix environment --pure --ad-hoc 
> guile-next guile3.0-hashing -- guile ~/tmp/sha256.scm
>
> ;;; (hash "b33576331465a60b003573541bf3b1c205936a16c407bc69f8419a527bf5c988")
> clock utime stime cutime cstime gctime
> 65.17 89.75  0.45   0.00   0.00  35.63

The patch below gives us:

--8<---cut here---start->8---
ludo@ribbon /tmp/hashing$ guile --r6rs -L .. ~/tmp/sha256.scm

;;; (hash "b33576331465a60b003573541bf3b1c205936a16c407bc69f8419a527bf5c988")
clock utime stime cutime cstime gctime
59.31 80.65  0.39   0.00   0.00  30.73
--8<---cut here---end--->8---

It’s a disappointingly small improvement.  The reason is that (hashing
fixnums) adds another layer of opacity, where it ends up doing
essentially:

  (define fx32xor fxxor)
  …

Thus, no inlining, and no easy trick to solve that.  :-/

Anyhow, I think the patch is probably a good idea.  WDYT?

Thanks,
Ludo’.

diff --git a/module/rnrs/arithmetic/fixnums.scm b/module/rnrs/arithmetic/fixnums.scm
index 4ec1cae0c..c30807eb5 100644
--- a/module/rnrs/arithmetic/fixnums.scm
+++ b/module/rnrs/arithmetic/fixnums.scm
@@ -1,6 +1,6 @@
 ;;; fixnums.scm --- The R6RS fixnums arithmetic library
 
-;;  Copyright (C) 2010, 2011, 2013 Free Software Foundation, Inc.
+;;  Copyright (C) 2010, 2011, 2013, 2020 Free Software Foundation, Inc.
 ;;
 ;; This library is free software; you can redistribute it and/or
 ;; modify it under the terms of the GNU Lesser General Public
@@ -75,25 +75,26 @@
 	  fxrotate-bit-field
 	  fxreverse-bit-field)
   (import (only (guile) ash
-		cons*
-			define-inlinable
-			inexact->exact
-			logand
-			logbit?
-			logcount
-			logior
-			lognot
-			logxor
-			most-positive-fixnum 
-			most-negative-fixnum
-			object-address)
+		cons*
+		define-inlinable
+		inexact->exact
+		logand
+		logbit?
+		logcount
+		logior
+		lognot
+		logxor
+		most-positive-fixnum 
+		most-negative-fixnum
+		object-address)
 	  (ice-9 optargs)
 	  (rnrs base (6))
 	  (rnrs control (6))
 	  (rnrs arithmetic bitwise (6))
 	  (rnrs conditions (6))
 	  (rnrs exceptions (6))
-	  (rnrs lists (6)))
+  (rnrs lists (6))
+  (rnrs syntax-case (6)))
 
   (define fixnum-width
 (let ((w (do ((i 0 (+ 1 i))
@@ -121,70 +122,105 @@
 (or (for-all inline-fixnum? args) (raise (make-assertion-violation
 
   (define-syntax define-fxop*
+(lambda (s)
+  (syntax-case s ()
+((_ name op)
+ (with-syntax ((proc (datum->syntax
+  #'name
+  (string->symbol
+   (string-append "%"
+  (symbol->string
+   (syntax->datum #'name))
+  "-proc")
+   #'(begin
+   ;; Define a procedure for when the inline case doesn't
+   ;; apply.
+   (define proc
+ (case-lambda
+   ((x y)
+(assert-fixnum x y)
+(op x y))
+   (args
+(assert-fixnums args)
+(apply op args
+
+   (define-syntax name
+ (lambda (s)
+   (syntax-case s ()
+ ((_ args (... ...))
+  #'(begin
+  (assert-fixnum args (... ...))
+  (op args (... ...
+ (x
+  (identifier? #'x)
+  #'proc))
+
+  (define-syntax define-alias
 (syntax-rules ()
-  ((_ name op)
-   (define name
-	(case-lambda
-	  ((x y)
-	   (assert-fixnum x y)
-	   (op x y))
-	  (args
-	   (assert-fixnums args)
-   (apply op args)))
+  ((_ new old)
+   (define-syntax new (identifier-syntax old)
 
   ;; All these predicates don't check their arguments for fixnum-ness,
   ;; as this doesn't seem to be strictly required by R6RS.
 
-  (define fx=? =)
-  (define fx>? >)
-  (define fx=? >=)
-  (define fx<=? <=)
+  (define-alias fx=? =)
+  (define-alias fx>? >)
+  (define-alias fx=? >=)
+  (define-alias fx<=? <=)
 
-  (define fxzero? zero?)
-  (define fxpositive? positive?)
-  (define fxnegative? negative?)
-  (define fxodd? odd?)
-  (define fxeven? even?)
+  (define-alias fxzero? zero?)
+  (define-alias fxpositive? positive?)
+  (define-alias fxnegative? negative?)
+  (define-alias fxodd? odd?)
+  (define-alias fxeven? even?)
 
   (define-fxop* fxmax max)
   (define-fxop* fxmin min)
 
-  (define (fx+ fx1 fx2)
+  (define-inlinable (fx+ fx1 fx2)
 (assert-fixnum fx1 fx2) 
 (let ((r (+ fx1 fx2))) 
   (or (inline-fixnum? r)
   (raise (make-implementation-restriction-violation)))
   r))
 
-  (define (fx* fx1 fx2)
+  (define-inlinable (fx* fx1 fx2)
 (assert-fixnum 

SHA256 performance with Guile 2.2 vs. Guile 3.0

2020-01-03 Thread Ludovic Courtès
Hello Guilers!

Göran Weinholt wrote a pure-Scheme (R6RS) implementation of common
cryptographic hash functions:

  https://github.com/weinholt/hashing

I thought this would make a useful benchmark (and probably favorable to
JIT because it’s one hot loop), so here goes (computing the SHA256 hash
of ‘guile-2.2.6.tar.xz’ with the code below, compiled with -O2, Guile
2.2.6 vs. 2.9.8):

--8<---cut here---start->8---
ludo@ribbon ~/src/guix$ ./pre-inst-env guix environment --pure --ad-hoc guile 
guile-hashing -- guile ~/tmp/sha256.scm

;;; (hash "b33576331465a60b003573541bf3b1c205936a16c407bc69f8419a527bf5c988")
clock utime stime cutime cstime gctime
135.07 164.13  0.52   0.00   0.00  42.14
ludo@ribbon ~/src/guix$ ./pre-inst-env guix environment --pure --ad-hoc 
guile-next guile3.0-hashing -- guile ~/tmp/sha256.scm

;;; (hash "b33576331465a60b003573541bf3b1c205936a16c407bc69f8419a527bf5c988")
clock utime stime cutime cstime gctime
65.17 89.75  0.45   0.00   0.00  35.63
--8<---cut here---end--->8---

Guile 3 is twice as fast!  No difference if we force ‘-O3’.

Still far from the libgcrypt implementation in C + asm, but hey!

--8<---cut here---start->8---
ludo@ribbon ~/src/guix$ time guix hash -f hex 
"/gnu/store/zfp7d4wr5hbl5lrnzs8c15bsc3ygq74g-guile-2.2.6.tar.xz"
b33576331465a60b003573541bf3b1c205936a16c407bc69f8419a527bf5c988

real0m0.097s
user0m0.093s
sys 0m0.024s
--8<---cut here---end--->8---

To be continued…

Ludo’.

(use-modules (hashing sha-2)
 (rnrs bytevectors)
 (ice-9 binary-ports)
 (ice-9 match)
 (ice-9 time))

(define (port-sha256 port)
  ;; Return the SHA256 of the data read from PORT.
  (define bv (make-bytevector 65536))
  (define hash (make-sha-256))

  (let loop ()
(match (get-bytevector-n! port bv 0
  (bytevector-length bv))
  ((? eof-object?)
   (sha-256-finish! hash)
   hash)
  (n
   (sha-256-update! hash bv 0 n)
   (loop)

(define (file-sha256 file)
  ;; Return the SHA256 of FILE.
  (call-with-input-file file port-sha256))

(time (pk 'hash (sha-256->string (file-sha256 
"/gnu/store/zfp7d4wr5hbl5lrnzs8c15bsc3ygq74g-guile-2.2.6.tar.xz"


Re-exporting a replaced binding

2020-01-03 Thread Ludovic Courtès
Hi again!

I’m not sure if this is an intended consequence of
cf08dbdc189f0005cab6f2ec7b23ed9d150ec43d, so I thought I’d share this
example of a practical effect:

--8<---cut here---start->8---
ludo@ribbon /tmp [env]$ cat x.scm
(define-module (x)
  #:use-module (srfi srfi-1)
  #:re-export (delete))
ludo@ribbon /tmp [env]$ cat y.scm
(define-module (y)
  #:use-module (x))

(pk 'delete delete)
ludo@ribbon /tmp [env]$ guile -L . -c '(use-modules (y))'
WARNING: (y): imported module (x) overrides core binding `delete'

;;; (delete #)
ludo@ribbon /tmp [env]$ guile --version
guile (GNU Guile) 2.9.8
--8<---cut here---end--->8---

Here ‘delete’ is replaced by srfi-1, but the replaced bit is not
propagated to module (x), even though (x) simply re-exports it.

Should the #:re-export clause propagate the replace bit, or should
it not?  :-)

(In Guile < 3.x, #:re-export would propagate the replace bit since that
bit was associated with the variable itself.)

Ludo’.



Re: GNU Guile 2.9.8 Released [beta]

2020-01-03 Thread tomas
On Fri, Jan 03, 2020 at 01:34:59PM +0800, Nala Ginrut wrote:
> When I was trying to compile Artanis, the configure threw an error:
> 
> checking for Guile version >= 3.0... configure: error: Guile 3.0 required,
> but 2.9.8 found
> 
> 
> Here's what I put in configure.ac:
> GUILE_PKG(2.2 2.3 2.9 3.0)
> 
> My question is "what's the correct config here"?

Hm. I think I had that with nyacc too. This worked for me:

  GUILE_PKG([3.0])
  GUILE_PROGS([2.9.5])

I think this is due to our currently apocalyptic [1] situation:

  tomas@trotzki:~/src/guile/nyacc$ guile
  GNU Guile 2.9.5
  [...]
  
  Enter `,help' for help.
  scheme@(guile-user)> (version)
  $1 = "2.9.5"
  scheme@(guile-user)> (effective-version)
  $2 = "3.0"

(replace 2.9.5 for 2.9.8 as appropriate).

Cheers
[1] Although apocalyptic has often a negative connotation, I'm using
   it here in its more original sense [2], i.e. full of gleeful
   expectation :-)

[2] https://en.wiktionary.org/wiki/apocalyptic

-- tomás


signature.asc
Description: Digital signature