Здравстуйте, есть задача сделать быстрый xor для большого буфера. Имеется процессор Quad-Core AMD Opteron(tm) Processor 2346 HE,
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 syscall nx mmxext fxsr_opt rdtscp lm 3dnowext 3dnow constant_tsc rep_good tsc_reliable nonstop_tsc pni cx16 popcnt hypervisor lahf_lm extapic abm sse4a misalignsse 3dnowprefetch
Делаю 3 варианта для теста, те что пришли в голову:
Вариант 1, самай простой через xorb:
for (i = 0; i < len; i++)
buf[i] ^= (char)key;
asm:
400780: 80 34 18 0c xorb $0xc,(%rax,%rbx,1)
Вариант 2, xor на 64 битных регистрах + хвост по байтам (xor инструкция):
__uint64_t *lbuf = (__uint64_t *)buf;
int llen = len % sizeof(__uint64_t);
for (i = 0; i < llen; i++)
lbuf[i] ^= lkey;
for (i = (llen * sizeof(__uint64_t)); i < (len - llen) ; i++)
buf[i] ^= (char)key;
asm:
4007f5: 48 8d 53 08 lea 0x8(%rbx),%rdx
4007f9: 31 c0 xor %eax,%eax
4007fb: 48 b9 0c 0c 0c 0c 0c mov $0xc0c0c0c0c0c0c0c,%rcx
400802: 0c 0c 0c
400805: 48 31 0b xor %rcx,(%rbx)
400808: 48 83 c0 01 add $0x1,%rax
40080c: 48 31 0a xor %rcx,(%rdx)
40080f: 48 3d 00 65 cd 1d cmp $0x1dcd6500,%rax
400815: 75 ee jne 400805 <test+0xa5>
400817: 31 f6 xor %esi,%esi
400819: 4c 89 e7 mov %r12,%rdi
Вариант 3, xor через 128 битныйу тип, SSE2 pxor инструкция + хвост по байтам:
__m128i *lbuf = (__m128i *)buf;
int llen = len % sizeof(__m128i);
for (i = 0; i < llen; i++)
lbuf[i] = __builtin_ia32_pxor128(lbuf[i], lkey);
for (i = (llen * sizeof( __m128i)); i < (len - llen) ; i++)
buf[i] ^= (char)key
asm:
400889: 66 0f 6f 0c 24 movdqa (%rsp),%xmm1
40088e: 31 d2 xor %edx,%edx
400890: 31 c0 xor %eax,%eax
400892: 66 0f 6f 04 18 movdqa (%rax,%rbx,1),%xmm0
400897: 66 0f ef c1 pxor %xmm1,%xmm0
40089b: 66 0f 7f 04 18 movdqa %xmm0,(%rax,%rbx,1)
4008a0: 48 83 c0 10 add $0x10,%rax
4008a4: 48 3d a0 00 00 00 cmp $0xa0,%rax
4008aa: 75 e6 jne 400892 <test+0x132>
4008ac: 48 83 c2 01 add $0x1,%rdx
4008b0: 48 81 fa 00 65 cd 1d cmp $0x1dcd6500,%rdx
4008b7: 75 d7 jne 400890 <test+0x130>
4008b9: 31 f6 xor %esi,%esi
4008bb: 4c 89 e7 mov %r12,%rdi
Теперь, самое интересное это циферки. Компилирую с -O2 и запускаю:
./a.out
test for i = 1000
duration 1 = 6665.891000
duration 2 = 2087.085000
duration 3 = 10276.917000
test for i = 100000
duration 1 = 6586.843000
duration 2 = 2090.889000
duration 3 = 10469.038000
test for i = 10000000
duration 1 = 6780.421000
duration 2 = 2082.808000
duration 3 = 10459.455000
i - размер буфера, duration - время для разных вариантов.
Теперь вопрос, это нормально что SSE2 инструкция работает медленнее, чем обычный xor на регистрах? Можно ли сделать xor быстрее?
Исходник теста положил сюда: http://codepaste.net/j1us7c
Ответ на:
комментарий
от AF
Ответ на:
комментарий
от sn1ln
Ответ на:
комментарий
от sn1ln
Ответ на:
комментарий
от maxxant
Ответ на:
комментарий
от sn1ln
Ответ на:
комментарий
от mv
Ответ на:
комментарий
от AF
Ответ на:
комментарий
от sn1ln
Ответ на:
комментарий
от sn1ln
Ответ на:
комментарий
от Dimanc
Ответ на:
комментарий
от Dimanc
Ответ на:
комментарий
от sn1ln
Ответ на:
комментарий
от sn1ln
Ответ на:
комментарий
от sn1ln
Ответ на:
комментарий
от anon_666
Ответ на:
комментарий
от mv
Ответ на:
комментарий
от anon_666
Ответ на:
комментарий
от sn1ln
Ответ на:
комментарий
от Yareg
Ответ на:
комментарий
от sn1ln
Ответ на:
комментарий
от mv
Ответ на:
комментарий
от Yareg
Ответ на:
комментарий
от mv
Ответ на:
комментарий
от Dimanc
Ответ на:
комментарий
от sn1ln
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.
Похожие темы
- Форум простой код на NASM (2024)
- Форум Методика поиска аналогичного кода в бинарном файле нового релиза. (2021)
- Форум NASM, GDB, LD (2012)
- Форум [x86_64/asm/c] использование параметров в C-функции (2011)
- Форум WiMAX Network Service 1.4 (2010)
- Статьи Линукс, ассемблер и X11 (2023)
- Форум [CL] XOR (2008)
- Форум Подсчёт XOR-суммы (2012)
- Форум Помогите с XOR (2020)
- Форум Криптостойкость XOR-шифра (2014)