use popcount table

This commit is contained in:
Ryan Culpepper 2012-12-18 09:44:22 -05:00
parent 139c0ca6c7
commit a6f03ee38f
2 changed files with 17 additions and 6 deletions

View File

@ -1,8 +1,9 @@
#lang racket/base #lang racket/base
(require (for-syntax racket/base) (require (for-syntax racket/base)
(for-syntax "private/count-bits-in-fixnum.rkt")
racket/private/vector-wraps racket/private/vector-wraps
racket/match racket/match
racket/dict racket/dict
racket/contract/base racket/contract/base
racket/fixnum racket/fixnum
racket/unsafe/ops racket/unsafe/ops
@ -90,9 +91,20 @@
(bit-vector-copy bv start end)])]) (bit-vector-copy bv start end)])])
bit-vector-copy)) bit-vector-copy))
(define popcount-table
(let ()
(define-syntax (make-table stx)
(with-syntax ([(elt ...)
(for/list ([i (in-range 256)])
(fxpopcount i))])
;; Literal immutable vector allocated once (?)
#'(quote #(elt ...))))
(make-table)))
(define (bit-vector-popcount bv) (define (bit-vector-popcount bv)
(for/sum ([b (in-bytes (bit-vector-words bv))]) (for/sum ([b (in-bytes (bit-vector-words bv))])
(unsafe-fxpopcount* b 8))) #| (unsafe-fxpopcount* b 8) |#
(unsafe-vector-ref popcount-table b)))
(define (bit-vector->list bv) (define (bit-vector->list bv)
(define len (bit-vector-size bv)) (define len (bit-vector-size bv))

View File

@ -1,6 +1,6 @@
#lang racket/base #lang racket/base
(require racket/unsafe/ops (require racket/unsafe/ops
(for-syntax racket/base racket/fixnum racket/vector)) (for-syntax racket/base racket/fixnum))
(provide fxpopcount (provide fxpopcount
unsafe-fxpopcount*) unsafe-fxpopcount*)
;; Count set bits for 30 bit number in 5 steps. ;; Count set bits for 30 bit number in 5 steps.
@ -43,13 +43,12 @@
(cond [(<= bits 8) lut8] (cond [(<= bits 8) lut8]
[(<= bits 30) lut30] [(<= bits 30) lut30]
[(<= bits 62) lut62] [(<= bits 62) lut62]
[else (raise-syntax-error "bit width too big" stx #'bits0)])] [else (raise-syntax-error "bit width too big" stx #'bits0)])])
[flut (vector-map bitwise-not lut)])
;; Unroll the addition loop ;; Unroll the addition loop
#`(let ([n expr]) #`(let ([n expr])
(let* #,(for/list ([m (in-vector lut)] (let* #,(for/list ([m (in-vector lut)]
[f (in-vector flut)]
[b (in-naturals)]) [b (in-naturals)])
(define f (bitwise-not m))
#`[n (unsafe-fx+ (unsafe-fxrshift (unsafe-fxand n #,m) #`[n (unsafe-fx+ (unsafe-fxrshift (unsafe-fxand n #,m)
#,(fxlshift 1 b)) #,(fxlshift 1 b))
(unsafe-fxand n #,f))]) (unsafe-fxand n #,f))])