>>> 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)
|