Skip to content

Commit

Permalink
Speed up BitArray packing
Browse files Browse the repository at this point in the history
Changes in convert(::BitArray, ::AbstractArray) and
dumpbitcache():
* avoid branches in for loops
* pack 8 Bools at a time
* use inbounds
  • Loading branch information
carlobaldassi committed Nov 12, 2015
1 parent 73242ec commit d7cd023
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 11 deletions.
8 changes: 2 additions & 6 deletions base/bitarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -310,21 +310,17 @@ function convert{T,N}(::Type{BitArray{N}}, A::AbstractArray{T,N})
ind = 1
@inbounds begin
for i = 1:length(Bc)-1
u = UInt64(1)
c = UInt64(0)
for j = 0:63
A[ind]!=0 && (c |= u)
c |= (UInt64(A[ind] != 0) << j)
ind += 1
u <<= 1
end
Bc[i] = c
end
u = UInt64(1)
c = UInt64(0)
for j = 0:_mod64(l-1)
A[ind]!=0 && (c |= u)
c |= (UInt64(A[ind] != 0) << j)
ind += 1
u <<= 1
end
Bc[end] = c
end
Expand Down
28 changes: 23 additions & 5 deletions base/broadcast.jl
Original file line number Diff line number Diff line change
Expand Up @@ -103,16 +103,34 @@ end
const bitcache_chunks = 64 # this can be changed
const bitcache_size = 64 * bitcache_chunks # do not change this

function bpack(z::UInt64)
z |= z >>> 7
z |= z >>> 14
z |= z >>> 28
z &= 0xFF
return z
end

function dumpbitcache(Bc::Vector{UInt64}, bind::Int, C::Vector{Bool})
ind = 1
nc = min(bitcache_chunks, length(Bc)-bind+1)
for i = 1:nc
u = UInt64(1)
C8 = reinterpret(UInt64, C)
nc8 = (nc >>> 3) << 3
@inbounds for i = 1:nc8
c = UInt64(0)
for j = 0:8:63
c |= (bpack(C8[ind]) << j)
ind += 1
end
Bc[bind] = c
bind += 1
end
ind = (ind-1) << 3 + 1
@inbounds for i = (nc8+1):nc
c = UInt64(0)
for j = 1:64
C[ind] && (c |= u)
for j = 0:63
c |= (UInt64(C[ind]) << j)
ind += 1
u <<= 1
end
Bc[bind] = c
bind += 1
Expand Down

0 comments on commit d7cd023

Please sign in to comment.