Skip to content

Commit

Permalink
Update Crystal version to 1.14 and run code formatter
Browse files Browse the repository at this point in the history
Locally I'm seeing the following improvements

suite                         | % improvement
----------------------------- | -------------
marghidanu                    |  12.2%
GordonBGood_bittwiddle        |   0.2%
GordonBGood_stride8           |   4.1%
GordonBGood_stride8-rblock16K | -10.9%
GordonBGood_extreme           |   1.8%
GordonBGood_extreme-hybrid    |   8.0%
  • Loading branch information
Fryguy committed Oct 21, 2024
1 parent 887109f commit c6edae3
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 28 deletions.
6 changes: 3 additions & 3 deletions PrimeCrystal/solution_1/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
FROM crystallang/crystal:1.0.0-alpine AS build
FROM crystallang/crystal:1.14-alpine AS build

WORKDIR /opt/app
COPY primes.cr .
RUN crystal build primes.cr --release --static --no-debug

FROM alpine:3.13
FROM alpine:3

COPY --from=build /opt/app/primes /usr/local/bin/

ENTRYPOINT [ "primes" ]
ENTRYPOINT [ "primes" ]
2 changes: 1 addition & 1 deletion PrimeCrystal/solution_2/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM debian:11

ENV CRYSTAL_VER="1.1"
ENV CRYSTAL_VER="1.14"

WORKDIR /opt

Expand Down
47 changes: 23 additions & 24 deletions PrimeCrystal/solution_2/primes.cr
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ end
BITMASKP = Pointer.malloc(8) { |i| 1_u8 << i }

macro unroll_setbits(bitarrp, starti, limiti, stepi)
ndx: Int32 = {{starti}} & 7
ndx : Int32 = {{starti}} & 7
r0 = {{starti}} >> 3
r1 = {{starti}} + {{stepi}}
r2 = r1 + {{stepi}}
Expand All @@ -47,8 +47,8 @@ macro unroll_setbits(bitarrp, starti, limiti, stepi)
r3 = (r3 >> 3) - r0
r2 = (r2 >> 3) - r0
r1 = (r1 >> 3) - r0
bytep: Pointer(UInt8) = {{bitarrp}} + r0
looplmtp: Pointer(UInt8) = {{bitarrp}} + (({{limiti}} >> 3) - r7)
bytep : Pointer(UInt8) = {{bitarrp}} + r0
looplmtp : Pointer(UInt8) = {{bitarrp}} + (({{limiti}} >> 3) - r7)
case ((({{stepi}} & 7) << 3) | ({{starti}} & 7)).to_u8
{% for n in (0_u8..0x3F) %}
when {{n}}
Expand Down Expand Up @@ -77,37 +77,37 @@ end
# swi = (ndx + ndx) * (ndx + 3) + 3
# r = ((swi | 63) + 1 - swi) % (ndx + ndx + 3)
# starti = if r == 0 then 0 else ndx + ndx + 3 - r
STARTIS = [ 2, 2, 1, 2, 6, 7, 13, 2, 6, 5, 12, 16, 6, 0, 29, 0,
6, 16, 30, 25, 6, 32, 45, 32, 6, 48, 30, 16, 6, 0, 62 ]
STARTIS = [2, 2, 1, 2, 6, 7, 13, 2, 6, 5, 12, 16, 6, 0, 29, 0,
6, 16, 30, 25, 6, 32, 45, 32, 6, 48, 30, 16, 6, 0, 62]

macro dense_setbits(bitarrp, starti, limiti, stepi)
dndx = {{starti}}
dndxlmt = {{starti}} | 63
while dndx <= dndxlmt # cull to an even 64-bit boundary...
{{bitarrp}}[dndx >> 3] |= BITMASKP[dndx & 7]; dndx += {{stepi}}
end
wordp: Pointer(UInt64) = ({{bitarrp}} + ((dndx >> 3) & (-8))).as(Pointer(UInt64))
wordp : Pointer(UInt64) = ({{bitarrp}} + ((dndx >> 3) & (-8))).as(Pointer(UInt64))
keep = wordp
wordlmtp: Pointer(UInt64) = ({{bitarrp}} + ((({{limiti}} >> 3) & (-8)) -
wordlmtp : Pointer(UInt64) = ({{bitarrp}} + ((({{limiti}} >> 3) & (-8)) -
(({{stepi}} << 3) - 8))).as(Pointer(UInt64))
dndx &= 63
case {{stepi}}.to_u8
{% for stpvi in (0...STARTIS.size) %} # odd primes STARTIS.size
when {{stpvi + stpvi + 3}}.to_u8
while wordp <= wordlmtp
# for all modulo pattern 64-bit words
{% for wi in (0 ... (stpvi + stpvi + 3)) %}
{% for wi in (0...(stpvi + stpvi + 3)) %}
# for all modulo pattern 64-bit words
{% for bi in (((wi * 64 - 1 - STARTIS[stpvi]) / (stpvi + stpvi + 3) + 1) .. ((wi * 64 + 63 - STARTIS[stpvi]) / (stpvi + stpvi + 3))) %}
{% if (STARTIS[stpvi] + (bi - 1) * (stpvi + stpvi + 3)) < wi * 64 && (STARTIS[stpvi] + (bi + 1) * (stpvi + stpvi + 3)) >= (wi + 1) * 64 %} # only one bit
{% for bi in (((wi * 64 - 1 - STARTIS[stpvi]) / (stpvi + stpvi + 3) + 1)..((wi * 64 + 63 - STARTIS[stpvi]) / (stpvi + stpvi + 3))) %}
{% if (STARTIS[stpvi] + (bi - 1) * (stpvi + stpvi + 3)) < wi * 64 && (STARTIS[stpvi] + (bi + 1) * (stpvi + stpvi + 3)) >= (wi + 1) * 64 %} # only one bit
wordp[{{wi}}] |= {{1_u64 << ((STARTIS[stpvi] + bi * (stpvi + stpvi + 3)) & 63)}}
{% elsif (STARTIS[stpvi] + (bi - 1) * (stpvi + stpvi + 3)) < wi * 64 %} # first bit of many in word
v = wordp[{{wi}}] | {{1_u64 << ((STARTIS[stpvi] + bi * (stpvi + stpvi + 3)) & 63)}}
{% elsif (STARTIS[stpvi] + (bi + 1) * (stpvi + stpvi + 3)) >= (wi + 1) * 64 %} # last bit of many in word
wordp[{{wi}}] = v | {{1_u64 << ((STARTIS[stpvi] + bi * (stpvi + stpvi + 3)) & 63)}}
{% else %} # not the first nor the last bit in the word
v |= {{1_u64 << ((STARTIS[stpvi] + bi * (stpvi + stpvi + 3)) & 63)}}
{% end %}
{% end %}
{% end %}
{% end %}
wordp += {{stpvi + stpvi + 3}}
Expand Down Expand Up @@ -140,7 +140,6 @@ class PrimeSieve
bap[swi >> 3] |= BITMASKP[swi & 7]; swi += bp
end
end

in Techniques::Stride8
(0..).each do |i|
swi = (i + i) * (i + 3) + 3 # calculate start marking index
Expand All @@ -158,7 +157,6 @@ class PrimeSieve
swi += bp
end
end

in Techniques::Stride8Block16K
strtsp = Pointer.malloc(8, nil.as Pointer(UInt8))
(0..).each do |i|
Expand All @@ -176,17 +174,16 @@ class PrimeSieve
mask = BITMASKP[si]; bytendxp = strtsp[si]
while bytendxp <= blockstopp
bytendxp[0] |= mask; bytendxp[bp] |= mask
bytendxp[bp2] |= mask; bytendxp[bp3] |= mask ; bytendxp += bp4
bytendxp[bp2] |= mask; bytendxp[bp3] |= mask; bytendxp += bp4
end
while bytendxp <= blocklmtp
bytendxp[0] |= mask ; bytendxp += bp
bytendxp[0] |= mask; bytendxp += bp
end
strtsp[si] = bytendxp
end
pagebytendx += CPUL1CACHE
end
end

in Techniques::Extreme
(0..).each do |i|
swi = (i + i) * (i + 3) + 3 # calculate start marking index
Expand All @@ -208,7 +205,7 @@ class PrimeSieve
end
end
end
end
end

def count_primes
if @range < 3
Expand Down Expand Up @@ -245,8 +242,8 @@ def bench(tec : Techniques)
end
if duration >= FORTO
prime_count = sieve.count_primes
count = sieve.@range < 2 ? 0 : 1
(0 .. ((sieve.@range - 3) >> 1).to_i32).each do |i|
count = sieve.@range < 2 ? 0 : 1
(0..((sieve.@range - 3) >> 1).to_i32).each do |i|
count += 1 if (sieve.@bufp[i >> 3] & BITMASKP[i & 7]) == 0
end
valid = count == EXPECTED && prime_count == EXPECTED
Expand All @@ -256,21 +253,23 @@ def bench(tec : Techniques)
printf("Invalid result!!!: ")
end
STDERR.printf("Passes: %d Time: %f Avg: %f Limit: %d Count1: %d Count2: %d Valid: %s\n",
passes, duration, (duration / passes),
sieve.@range, count, prime_count, valid)
passes, duration, (duration / passes),
sieve.@range, count, prime_count, valid)
break
end
end
end

{% if flag? :expand_macro %} # only one bit
{% if flag? :expand_macro %}
# only one bit
bap = Pointer.malloc(16384, 0_u8)
bp = 3
swi = (bp * bp - 3) >> 3
lmti = 131071
unroll_setbits(bap, swi, lmti, bp)
dense_setbits(bap, swi, lmti, bp)
{% else %}
Techniques.each do |t| bench(t) end
Techniques.each do |t|
bench(t)
end
{% end %}

0 comments on commit c6edae3

Please sign in to comment.