Последний раз редактировалось feedinglight 10.02.2020, 13:33, всего редактировалось 1 раз.
С опцией gcc 9.2 -O3 -funroll-loops оператор __restrict немного меняет код. gcc 8.1 выдаёт код чуть короче(с метками), тоже __restrict меняет код. Скорость - не знаю. void func(bool *pnt1, const bool *pnt2, const int N)
{
for (int i = 0; i < N; i++)
{
*pnt1 = !*pnt2;
pnt1++;
pnt2++;
}
}
func(bool*, bool const*, int):
test edx, edx
jle .L1
xor r9d, r9d
lea ecx, [rdx-1]
and edx, 7
je .L3
cmp rdx, 1
je .L26
cmp rdx, 2
je .L27
cmp rdx, 3
je .L28
cmp rdx, 4
je .L29
cmp rdx, 5
je .L30
cmp rdx, 6
jne .L41
.L31:
movzx edx, BYTE PTR [rsi+r9]
xor edx, 1
mov BYTE PTR [rdi+r9], dl
add r9, 1
.L30:
movzx r8d, BYTE PTR [rsi+r9]
xor r8d, 1
mov BYTE PTR [rdi+r9], r8b
add r9, 1
.L29:
movzx r10d, BYTE PTR [rsi+r9]
xor r10d, 1
mov BYTE PTR [rdi+r9], r10b
add r9, 1
.L28:
movzx r11d, BYTE PTR [rsi+r9]
xor r11d, 1
mov BYTE PTR [rdi+r9], r11b
add r9, 1
.L27:
movzx eax, BYTE PTR [rsi+r9]
xor eax, 1
mov BYTE PTR [rdi+r9], al
add r9, 1
.L26:
movzx edx, BYTE PTR [rsi+r9]
mov r8, r9
xor edx, 1
mov BYTE PTR [rdi+r9], dl
add r9, 1
cmp rcx, r8
je .L42
.L3:
movzx r10d, BYTE PTR [rsi+r9]
xor r10d, 1
mov BYTE PTR [rdi+r9], r10b
movzx r11d, BYTE PTR [rsi+1+r9]
xor r11d, 1
mov BYTE PTR [rdi+1+r9], r11b
movzx eax, BYTE PTR [rsi+2+r9]
xor eax, 1
mov BYTE PTR [rdi+2+r9], al
movzx edx, BYTE PTR [rsi+3+r9]
lea rax, [r9+7]
xor edx, 1
mov BYTE PTR [rdi+3+r9], dl
movzx r8d, BYTE PTR [rsi+4+r9]
xor r8d, 1
mov BYTE PTR [rdi+4+r9], r8b
movzx r10d, BYTE PTR [rsi+5+r9]
xor r10d, 1
mov BYTE PTR [rdi+5+r9], r10b
movzx r11d, BYTE PTR [rsi+6+r9]
xor r11d, 1
mov BYTE PTR [rdi+6+r9], r11b
movzx edx, BYTE PTR [rsi+7+r9]
xor edx, 1
mov BYTE PTR [rdi+7+r9], dl
add r9, 8
cmp rcx, rax
jne .L3
.L1:
ret
.L41:
movzx eax, BYTE PTR [rsi]
mov r9d, 1
xor eax, 1
mov BYTE PTR [rdi], al
jmp .L31
.L42:
ret
void func(bool *__restrict pnt1, const bool *__restrict pnt2, const int N)
{
for (int i = 0; i < N; i++)
{
*pnt1 = !*pnt2;
pnt1++;
pnt2++;
}
}
func(bool*, bool const*, int):
test edx, edx
jle .L1
xor r9d, r9d
lea ecx, [rdx-1]
and edx, 7
je .L3
cmp rdx, 1
je .L26
cmp rdx, 2
je .L27
cmp rdx, 3
je .L28
cmp rdx, 4
je .L29
cmp rdx, 5
je .L30
cmp rdx, 6
jne .L41
.L31:
movzx edx, BYTE PTR [rsi+r9]
xor edx, 1
mov BYTE PTR [rdi+r9], dl
add r9, 1
.L30:
movzx r8d, BYTE PTR [rsi+r9]
xor r8d, 1
mov BYTE PTR [rdi+r9], r8b
add r9, 1
.L29:
movzx r10d, BYTE PTR [rsi+r9]
xor r10d, 1
mov BYTE PTR [rdi+r9], r10b
add r9, 1
.L28:
movzx r11d, BYTE PTR [rsi+r9]
xor r11d, 1
mov BYTE PTR [rdi+r9], r11b
add r9, 1
.L27:
movzx eax, BYTE PTR [rsi+r9]
xor eax, 1
mov BYTE PTR [rdi+r9], al
add r9, 1
.L26:
movzx edx, BYTE PTR [rsi+r9]
mov r8, r9
xor edx, 1
mov BYTE PTR [rdi+r9], dl
add r9, 1
cmp rcx, r8
je .L42
.L3:
movzx r10d, BYTE PTR [rsi+r9]
movzx r11d, BYTE PTR [rsi+1+r9]
movzx edx, BYTE PTR [rsi+3+r9]
movzx eax, BYTE PTR [rsi+2+r9]
xor r10d, 1
xor r11d, 1
movzx r8d, BYTE PTR [rsi+4+r9]
xor edx, 1
mov BYTE PTR [rdi+r9], r10b
movzx r10d, BYTE PTR [rsi+5+r9]
xor eax, 1
mov BYTE PTR [rdi+1+r9], r11b
movzx r11d, BYTE PTR [rsi+6+r9]
xor r8d, 1
mov BYTE PTR [rdi+3+r9], dl
movzx edx, BYTE PTR [rsi+7+r9]
xor r10d, 1
mov BYTE PTR [rdi+2+r9], al
xor r11d, 1
lea rax, [r9+7]
xor edx, 1
mov BYTE PTR [rdi+4+r9], r8b
mov BYTE PTR [rdi+5+r9], r10b
mov BYTE PTR [rdi+6+r9], r11b
mov BYTE PTR [rdi+7+r9], dl
add r9, 8
cmp rcx, rax
jne .L3
.L1:
ret
.L41:
movzx eax, BYTE PTR [rsi]
mov r9d, 1
xor eax, 1
mov BYTE PTR [rdi], al
jmp .L31
.L42:
ret
Если условия завершения цикла сложные, то можно вручную разворачивать циклы, вставив внутрь фиксированный цикл от 0 до 31, например, и добавив необходимые фиктивные элементы в массивах. Ветвления тормозят (на моём core2 duo по крайней мере). А если так важна скорость, то можно под конкретный процессор написать. -- 10.02.2020, 14:33 --А может сейчас простые циклы процессор уже разворачивает, раз O3 не разворачивает по умолчанию, странно.
|