Skip to content

Commit

Permalink
Go back to unsafe, but safe
Browse files Browse the repository at this point in the history
  • Loading branch information
projekter committed Jun 1, 2024
1 parent 3632725 commit 1b77406
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 24 deletions.
4 changes: 2 additions & 2 deletions src/BlitSort.jl
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ function blit_reverse_partition!(array, array_index::Int, swap, swap_index::Int,
end
m = pta - array_index

copyto!(array, pta, swap, swap_index, nmemb - m)
_unsafe_copyto!(array, pta, swap, swap_index, nmemb - m)

return asUInt(m)
end
Expand Down Expand Up @@ -375,7 +375,7 @@ function blit_default_partition!(array, array_index::Int, swap, swap_index::Int,
end
m = pta - array_index

copyto!(array, pta, swap, swap_index, nmemb - m)
_unsafe_copyto!(array, pta, swap, swap_index, nmemb - m)

return asUInt(m)
end
Expand Down
44 changes: 22 additions & 22 deletions src/QuadSort.jl
Original file line number Diff line number Diff line change
Expand Up @@ -446,25 +446,25 @@ function cross_merge!(dest, dest_index::Int, from, from_index::Int, left::UInt,
while tpl - ptl > 8 && tpr - ptr > 8
@label ptl8_ptr
if cmp(from[ptl+7], from[ptr]) 0
copyto!(dest, ptd, from, ptl, 8); ptd += 8; ptl += 8
_unsafe_copyto!(dest, ptd, from, ptl, 8); ptd += 8; ptl += 8
tpl - ptl > 8 && @goto ptl8_ptr
break
end
@label ptl_ptr8
if cmp(from[ptl], from[ptr+7]) > 0
copyto!(dest, ptd, from, ptr, 8); ptd += 8; ptr += 8
_unsafe_copyto!(dest, ptd, from, ptr, 8); ptd += 8; ptr += 8
tpr - ptr > 8 && @goto ptl_ptr8
break
end
@label tpl_tpr8
if cmp(from[tpl], from[tpr-7]) 0
tpd -= 8; tpr -= 8; copyto!(dest, tpd +1, from, tpr +1, 8)
tpd -= 8; tpr -= 8; _unsafe_copyto!(dest, tpd +1, from, tpr +1, 8)
tpr - ptr > 8 && @goto tpl_tpr8
break
end
@label tpl8_tpr
if cmp(from[tpl-7], from[tpr]) > 0
tpd -= 8; tpl -= 8; copyto!(dest, tpd +1, from, tpl +1, 8)
tpd -= 8; tpl -= 8; _unsafe_copyto!(dest, tpd +1, from, tpl +1, 8)
tpl - ptl > 8 && @goto tpl8_tpr
end
loop = 8
Expand Down Expand Up @@ -515,10 +515,10 @@ function quad_merge_block!(array, array_index::Int, swap, swap_index::Int, block
cross_merge!(swap, swap_index + asInt(block_x_2), array, pt2, block, block, cmp)
elseif tmp == 2
cross_merge!(swap, swap_index, array, array_index, block, block, cmp)
copyto!(swap, swap_index + asInt(block_x_2), array, pt2, block_x_2)
_unsafe_copyto!(swap, swap_index + asInt(block_x_2), array, pt2, block_x_2)
elseif tmp == 3
cmp(array[pt2-1], array[pt2]) 0 && return
copyto!(swap, swap_index, array, array_index, 2block_x_2)
_unsafe_copyto!(swap, swap_index, array, array_index, 2block_x_2)
end
cross_merge!(array, array_index, swap, swap_index, block_x_2, block_x_2, cmp)
end
Expand Down Expand Up @@ -549,7 +549,7 @@ function partial_forward_merge!(array, array_index::Int, swap, swap_index::Int,
tpr = array_index + asInt(nmemb) -1
cmp(array[ptr-1], array[ptr]) 0 && return

copyto!(swap, swap_index, array, array_index, block)
_unsafe_copyto!(swap, swap_index, array, array_index, block)
ptl = swap_index
tpl = swap_index + asInt(block) -1
while ptl < tpl -1 && ptr < tpr -1
Expand Down Expand Up @@ -598,11 +598,11 @@ function partial_backward_merge!(array, array_index::Int, swap, swap_index::Int,
right = nmemb - block
if nmemb swap_size && right 64
cross_merge!(swap, swap_index, array, array_index, block, right, cmp)
copyto!(array, array_index, swap, swap_index, nmemb)
_unsafe_copyto!(array, array_index, swap, swap_index, nmemb)
return
end

copyto!(swap, swap_index, array, array_index + asInt(block), right)
_unsafe_copyto!(swap, swap_index, array, array_index + asInt(block), right)
tpr = swap_index + asInt(right) -1
while tpl > array_index +16 && tpr > swap_index +16
@label tpl_tpr16
Expand Down Expand Up @@ -717,22 +717,22 @@ function trinity_rotation!(array, array_index::Int, swap, swap_index::Int, swap_
end
if left < right
if left swap_size
copyto!(swap, swap_index, array, array_index, left)
copyto!(array, array_index, array, array_index + asInt(left), right)
copyto!(array, array_index + asInt(right), swap, swap_index, left)
_unsafe_copyto!(swap, swap_index, array, array_index, left)
_unsafe_copyto!(array, array_index, array, array_index + asInt(left), right)
_unsafe_copyto!(array, array_index + asInt(right), swap, swap_index, left)
else
pta = array_index
ptb = pta + asInt(left)
bridge = right - left
if bridge swap_size && bridge > 3
ptc = pta + asInt(right)
ptd = ptc + asInt(left)
copyto!(swap, swap_index, array, ptb, bridge)
_unsafe_copyto!(swap, swap_index, array, ptb, bridge)
for _ in 1:left
array[ptc -= 1] = array[ptd -= 1]
array[ptd] = array[ptb -= 1]
end
copyto!(array, pta, swap, swap_index, bridge)
_unsafe_copyto!(array, pta, swap, swap_index, bridge)
else
ptc = ptb
ptd = ptc + asInt(right)
Expand All @@ -758,25 +758,25 @@ function trinity_rotation!(array, array_index::Int, swap, swap_index::Int, swap_
end
elseif right < left
if right swap_size
copyto!(swap, swap_index, array, array_index + asInt(left), right)
copyto!(array, array_index + asInt(right), array, array_index, left)
copyto!(array, array_index, swap, swap_index, right)
_unsafe_copyto!(swap, swap_index, array, array_index + asInt(left), right)
_unsafe_copyto_backwards!(array, array_index + asInt(right), array, array_index, left)
_unsafe_copyto!(array, array_index, swap, swap_index, right)
else
pta = array_index
ptb = pta + asInt(left)
bridge = left - right
if bridge swap_size && bridge > 3
ptc = pta + asInt(right)
ptd = ptc + asInt(left)
copyto!(swap, swap_index, array, ptc, bridge)
_unsafe_copyto!(swap, swap_index, array, ptc, bridge)
for _ in 1:right
array[ptc] = array[pta]
array[pta] = array[ptb]
ptc += 1
pta += 1
ptb += 1
end
copyto!(array, ptd - asInt(bridge), swap, swap_index, bridge)
_unsafe_copyto!(array, ptd - asInt(bridge), swap, swap_index, bridge)
else
ptc = ptb
ptd = ptc + asInt(right)
Expand Down Expand Up @@ -847,9 +847,9 @@ function rotate_merge_block!(array, array_index::Int, swap, swap_index::Int, swa

if !iszero(left)
if lblock + left swap_size
copyto!(swap, swap_index, array, array_index, lblock)
copyto!(swap, swap_index + lblocki, array, array_index + lblocki + rblocki, left)
copyto!(array, array_index + lblocki + asInt(left), array, array_index + lblocki, rblock)
_unsafe_copyto!(swap, swap_index, array, array_index, lblock)
_unsafe_copyto!(swap, swap_index + lblocki, array, array_index + lblocki + rblocki, left)
_unsafe_copyto_backwards!(array, array_index + lblocki + asInt(left), array, array_index + lblocki, rblock)

cross_merge!(array, array_index, swap, swap_index, lblock, left, cmp)
else
Expand Down
11 changes: 11 additions & 0 deletions src/SortingAlgorithms.jl
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,17 @@ function _unsafe_copyto!(dest::Array, doffs, src::Array, soffs, n)
unsafe_copyto!(dest, doffs, src, soffs, n)
end

function _unsafe_copyto_backwards!(dest, doffs, src, soffs, n)
@inbounds for i in n-1:-1:0
dest[doffs + i] = src[soffs + i]
end
dest
end

function _unsafe_copyto_backwards!(dest::Array, doffs, src::Array, soffs, n)
unsafe_copyto!(dest, doffs, src, soffs, n)
end

# merge v[lo:m] and v[m+1:hi] ([A;B]) using scratch[1:1+hi-lo]
# This is faster than merge! but requires twice as much auxiliary memory.
function twoended_merge!(v::AbstractVector{T}, lo::Integer, m::Integer, hi::Integer, o::Ordering, scratch::AbstractVector{T}) where T
Expand Down

0 comments on commit 1b77406

Please sign in to comment.