You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Update set_global_shift_decrease! to shift weights rather than recomputing them (#112)
* Update `set_global_shift_decrease!` to shift weights rather than recomputing them, taking advantage of the fact that the shift is always down (note: this includes a bug) and add comments about invariants and a TODO
* Add test
* inline the only remaining call-site of recompute_range
Note: this does include some regressions, though the gestalt is positive and 5B′ is an improvement.
# The "weights are accurately computed" invariant is broken for weight_index, but the "sum(weights) == m[4]" invariant still holds
343
+
# set_global_shift_decrease! will do something wrong to weight_index, but preserve the "sum(weights) == m[4]" invariant.
342
344
set_global_shift_decrease!(m, m3) #TODO for perf: special case all call sites to this function to take advantage of known shift direction and/or magnitude; also try outlining
m[weight_index] = weight# The "weights are accurately computed" invariant is now restored
351
+
m4 = m[4]# The "sum(weights) == m[4]" invariant is broken
350
352
m4 -= old_weight
351
-
m4, o = Base.add_with_overflow(m4, weight)
353
+
m4, o = Base.add_with_overflow(m4, weight)# The "sum(weights) == m4" invariant now holds, though the computation overflows
352
354
if o
353
355
# If weights overflow (>2^64) then shift down by 16 bits
354
356
m3 = m[3]-0x10
@@ -491,8 +493,30 @@ function set_global_shift_increase!(m::Memory, m2, m3::UInt64, m4) # Increase sh
491
493
i <= -signed(m3)-122+4
492
494
So for -signed(m3)-118 < i, we could need to adjust the ith weight
493
495
=#
494
-
recompute_range =max(5, -signed(m3)-117):m2 #TODO It would be possible to scale this range with length (m[1]) in which case testing could be stricter and performance could be (marginally) better, though not in large cases so possibly not worth doing at all)
r1 = m2 #TODO It would be possible to scale this range with length (m[1]) in which case testing could be stricter and performance could be (marginally) better, though not in large cases so possibly not worth doing at all)
# i < -60-signed(m3); the low 64 bits are shifted off.
503
+
504
+
checkbounds(m, r0:2r1+2042)
505
+
@inboundsfor i in r0:min(r1, -61-signed(m3))
506
+
significand_sum_lo = m[_convert(Int, 2i+2041)]
507
+
significand_sum_hi = m[_convert(Int, 2i+2042)]
508
+
significand_sum_lo == significand_sum_hi ==0&&continue# in this case, the weight was and still is zero
509
+
shift =signed(i-4+m3) +64
510
+
m4 +=update_weight!(m, i, significand_sum_hi << shift)
511
+
end
512
+
@inboundsfor i inmax(r0,-60-signed(m3)):r1
513
+
significand_sum =get_significand_sum(m, i)
514
+
significand_sum ==0&&continue# in this case, the weight was and still is zero
515
+
shift =signed(i-4+m3)
516
+
m4 +=update_weight!(m, i, significand_sum << shift)
517
+
end
518
+
519
+
m[4] = m4
496
520
end
497
521
498
522
functionset_global_shift_decrease!(m::Memory, m3::UInt64, m4=m[4]) # Decrease shift, on insertion of elements
@@ -503,7 +527,7 @@ function set_global_shift_decrease!(m::Memory, m3::UInt64, m4=m[4]) # Decrease s
503
527
# In the case of adding a giant element, call this first, then add the element.
504
528
# In any case, this only adjusts elements at or before m[2]
505
529
# from the first index that previously could have had a weight > 1 to min(m[2], the first index that can't have a weight > 1) (never empty), set weights to 1 or 0
506
-
# from the first index that could have a weight > 1 to m[2] (possibly empty), recompute weights.
530
+
# from the first index that could have a weight > 1 to m[2] (possibly empty), shift weights by delta.
507
531
m2 =signed(m[2])
508
532
i1 =-signed(m3)-117# see above, this is the first index that could have weight > 1 (anything after this will have weight 1 or 0)
509
533
i1_old =-signed(m3_old)-117# anything before this is already weight 1 or 0
@@ -520,35 +544,18 @@ function set_global_shift_decrease!(m::Memory, m3::UInt64, m4=m[4]) # Decrease s
0 commit comments