>>> array = [3,2,4]
>>> array.sort()
>>> def compare_swap(array, a, b): ... if array[a] < array[b]: ... (array[a], array[b]) = (array[b], array[a]) ... >>> compare_swap(array, 0, 1) >>> compare_swap(array, 0, 2) >>> compare_swap(array, 1, 2)
>>> def compare_swap(array, a, b): ... if array[a] > array[b]: ... (array[a], array[b]) = (array[b], array[a]) ... >>> compare_swap(array, 0, 1) >>> compare_swap(array, 0, 2) >>> compare_swap(array, 1, 2)This is the corresponding sorting network notation (aka knuth diagram):
2E: MOV EAX, [EDX+1] ;;; (LET ((A (AREF ARR 0)) (B (AREF ARR 2))) ...) 31: MOV ECX, [EDX+9] 34: CMP EAX, ECX 36: JLE L0 38: MOV [EDX+1], ECX ;;; (SETF (AREF ARR 0) B (AREF ARR 2) A) 3B: MOV [EDX+9], EAX 3E: L0: MOV EAX, [EDX+1] ;;; (LET ((A (AREF ARR 0)) (B (AREF ARR 1))) ...) 41: MOV ECX, [EDX+5] 44: CMP EAX, ECX 46: JLE L1 48: MOV [EDX+1], ECX ;;; (SETF (AREF ARR 0) B (AREF ARR 1) A) 4B: MOV [EDX+5], EAX 4E: L1: MOV EAX, [EDX+5] ;;; (LET ((A (AREF ARR 1)) (B (AREF ARR 2))) ...) 51: MOV ECX, [EDX+9] 54: CMP EAX, ECX 56: JLE L2 58: MOV [EDX+5], ECX ;;; (SETF (AREF ARR 1) B (AREF ARR 2) A) 5B: MOV [EDX+9], EAX 5E: L2: ...
|
|
|
|
3x3 image kernel | Paeth's 9-element median filter | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
|
|
|
|
|
|
|
Possibly leaky | Constant-time (simple) | Constant-time (best) |
---|---|---|
int temp; if (a[i] < a[j]) { temp = a[i]; a[i] = a[j]; a[j] = temp; } |
int temp[2]; int noswap = !(a[i] < a[j]); temp[0] = a[i]; temp[1] = a[j]; a[i] = temp[!noswap]; a[j] = temp[noswap]; |
#define max(x, y) (x ^ ((x ^ y) & -(x < y))) #define min(x, y) (y ^ ((x ^ y) & -(x < y))) int temp; temp = max(a[i], a[j]); a[j] = min(a[i], a[j]); a[i] = temp; |
Possibly Leaky | |
---|---|
39: mov 0x4(%rdi),%edx ; 42: mov 0x44(%rdi),%r13d ; 46: cmp %r13d,%edx ; a[0] < a[16] 49: mov %edx,-0x4(%rsp) ; temp = a[0] 53: jge 0x400746 <+70> ; maybe goto 70 55: mov %r13d,0x4(%rdi) ; a[0] = a[16] 59: mov %r13d,-0x4(%rsp) ; 64: mov %edx,%r13d ; 67: mov %edx,0x44(%rdi) ; a[16] = temp 70: ... |
|
Constant-time (simple) | |
16: mov 0x40(%rdi),%edx 19: mov (%rdi),%ecx 21: cmp %edx,%ecx ; diff = !(a[0] < a[16]) 31: setge %al 27: mov %ecx,-0x8(%rsp) ; temp[0] = a[0] 23: mov %edx,-0x4(%rsp) ; temp[1] = a[16] 37: mov %eax,%edx 41: xor $0x1,%edx 48: movslq %edx,%rdx 51: mov -0x8(%rsp,%rdx,4),%edx 68: mov %edx,-0x30(%rsp) ; a[0] = temp[!diff] 39: cltq 44: mov -0x8(%rsp,%rax,4),%eax 59: mov %eax,-0x40(%rsp) ; a[16] = temp[diff] 63: mov %eax,0x40(%rdi) |
|
Intel Atom N550 (gcc 4.5.2)
|
AMD Athlon II X2 215 (gcc 4.4.3)
| ||||||||||||||||||||||||||||||||||||||||
SPARC sun4v (gcc 4.4.3)
|
ARM v7 rev 2 (gcc 4.4.5)
|