【发布时间】:2015-11-18 01:49:19
【问题描述】:
所以我正在为类编写一个 ARM 程序集快速排序方法。除了复杂性没有意义之外,我大部分都理解了。
我们将它与我们制作的另一种冒泡排序方法进行比较,它在具有 1 个参数和 10 个参数的示例中表现更好。但是我什至无法比较 100 参数测试,因为它花费的时间太长......我什至无法让它做 75,但 50 在几秒钟内完成。
这就是我所拥有的,
qsort: @ Takes three parameters:
@ a: Pointer to base of array a to be sorted (arrives in r0)
@ n: number of elements in the array (arrives in r1)
stmfd sp!, {r4, r6, lr} @ Save r4 and r6 for caller
mov r6, r1 @ r6 <- right
mov r2, #0 @ r2 <- left
qsort_tailcall_entry:
sub r7, r6, r2 @ If right - left <= 1 (already sorted),
cmp r7, #1
ldmlefd sp!, {r4, r6, pc} @ Return, restoring r4 and r6
ldr r7, [r0, r2, asl #2] @ r7 <- a[left], gets pivot element
add r1, r2, #1 @ l <- left + 1
mov r4, r6 @ r <- right
partition_loop:
ldr r3, [r0, r1, asl #2] @ r3 <- a[l]
cmp r3, r7 @ If a[l] <= pivot_element,
addle r1, r1, #1 @ ... increment l, and
ble partition_test @ ... continue to next iteration.
sub r4, r4, #1 @ Otherwise, decrement r,
ldr r8, [r0, r4, asl #2] @ ... and swap a[l] and a[r].
str r8, [r0, r1, asl #2]
str r3, [r0, r4, asl #2]
partition_test:
cmp r1, r4 @ If l < r,
blt partition_loop @ ... continue iterating.
partition_finish:
sub r1, r1, #1 @ Decrement l
ldr r3, [r0, r1, asl #2] @ Swap a[l] and pivot
str r3, [r0, r2, asl #2]
str r7, [r0, r1, asl #2]
bl qsort @ Call self recursively on left part,
@ with args a (r0), left (r2), r (r2),
@ also preserves r4 and r6
mov r2, r4
b qsort_tailcall_entry @ Tail-call self on right part,
@ with args a (r0), l (r2), right (r6)
谁能帮助我理解为什么它需要这么长时间并且呈指数级增长?我能做些什么来解决它?
【问题讨论】:
-
至少它的评论很好,我们在这里看不到太多(+1)......你如何为一个小数组(如 3 个项目)单步执行它,看看它是否有效预期的事情?
-
你在什么上面运行它,它有多少可用内存? “递归算法对足够大的数据很有趣”通常意味着你已经搞砸了。
-
会的。我对这种设置方式的灵感来自许多在线资源,因此我试图跟踪我在 cmets 中的位置。编辑:是的,我在 rasp pi 上运行它,所以这可能是问题所在。
-
来吧,100个元素? RPi 应该绰绰有余...
-
对我来说仍然是清晨,但是,使用快速排序最糟糕的事情是选择第一个元素作为枢轴并尝试对已经排序的数组进行排序。为了进行性能比较,我还会编写一个 C 版本,看看它的性能如何,看看问题是否出在 arm 实现中,看起来并不明显。