OSDev http://osdev.su/ |
|
Поддержка SSE2 в эмуляторах http://osdev.su/viewtopic.php?f=6&t=1032 |
Страница 1 из 1 |
Автор: | achesnokov [ 17 дек 2014, 22:29 ] |
Заголовок сообщения: | Поддержка SSE2 в эмуляторах |
Написал функцию memzero(), хотел применить SSE2 для оптимизации. Протестировал, не работает на эмуляторах (VMWare, Bochs, Oracle VirtualBox), падает на первой SSE-шной инструкции xorpd xmm0, xmm0. При этом на всех реальных компах, которые есть дома, эта же функция работает без проблем. В чем подвох? Поддержка SSE2 в том же Bochs декларирована... Можно, конечно без SSE2 обойтись... но обидно. Код: ; eax edx
;void memzero(void * mem, size_t size); ; section .text [BITS 32] global memzero memzero: pushf push edi cld mov edi, eax and eax, 0xf jz use_sse2 use_stos: mov ecx, edx mov eax, edx and eax, 0x3 jz zero_dwords and eax, 0x1 jz zero_words xor eax, eax rep stosb jmp end zero_words: shr ecx, 1 rep stosw jmp end zero_dwords: shr ecx, 2 rep stosd jmp end use_sse2: xorpd xmm0, xmm0 mov ecx, edx mov eax, edx and eax, 0x7f jz fast_sse2 and eax, 0xf jnz use_stos slow_sse2: movdqa [edi], xmm0 add edi, 16 sub ecx, 16 jnz slow_sse2 jmp end fast_sse2: movdqa [edi], xmm0 movdqa [edi + 16], xmm0 movdqa [edi + 32], xmm0 movdqa [edi + 48], xmm0 movdqa [edi + 64], xmm0 movdqa [edi + 80], xmm0 movdqa [edi + 96], xmm0 movdqa [edi + 112], xmm0 add edi, 128 sub ecx, 128 jnz fast_sse2 end: pop edi popf ret |
Автор: | pavia [ 17 дек 2014, 22:47 ] |
Заголовок сообщения: | Re: Поддержка SSE2 в эмуляторах |
Вроде как включить надо. http://wiki.osdev.org/SSE#Adding_support Раздел Adding support |
Автор: | pavia [ 17 дек 2014, 22:58 ] |
Заголовок сообщения: | Re: Поддержка SSE2 в эмуляторах |
Точно: Том 3А стр 577 глава 13.1.4 Initialization of the SSE/SSE2/SSE3/SSSE3/SSE4 Extensions |
Автор: | stlw [ 17 дек 2014, 23:05 ] |
Заголовок сообщения: | Re: Поддержка SSE2 в эмуляторах |
кстати, нет никакой разницы в реальнов процессоре между rep stosb/stosw/stosd. Вторые две внутри процессора умножают ECX на константу и вызывают stosb, так что твои разделения по data size бессмысленны. Кстати, на счет SSE - при размере в 128 байт и выше почти гарантированно stos будет будет быстрее, чем SSE вариант. У микрокода есть некий фиксированный overhead, который заметен при для коротких stos и movs, но чем больше длина - тем менее это заметно. По моему для размера в 128-256 байт тебе уже мало что светит и stos будет быстрее, особенно если ECX на 128 не делиться. И еще - movdqa сделает очень еффектный #GP если EDI не выровнен на 16 байт. Не вижу проверки в коде Станислав |
Автор: | achesnokov [ 18 дек 2014, 21:47 ] |
Заголовок сообщения: | Re: Поддержка SSE2 в эмуляторах |
pavia писал(а): Спасибо! Заработало в эмуляторах тоже. |
Автор: | achesnokov [ 18 дек 2014, 21:54 ] |
Заголовок сообщения: | Re: Поддержка SSE2 в эмуляторах |
stlw писал(а): кстати, нет никакой разницы в реальнов процессоре между rep stosb/stosw/stosd. Вторые две внутри процессора умножают ECX на константу и вызывают stosb, так что твои разделения по data size бессмысленны. Может быть, чего не знаю, того не знаю. stlw писал(а): Кстати, на счет SSE - при размере в 128 байт и выше почти гарантированно stos будет будет быстрее, чем SSE вариант. У микрокода есть некий фиксированный overhead, который заметен при для коротких stos и movs, но чем больше длина - тем менее это заметно. По моему для размера в 128-256 байт тебе уже мало что светит и stos будет быстрее, особенно если ECX на 128 не делиться. Вариант с SSE2 задумывается на большие длины. Когда, например надо память под процесс обнулить. Чтобы старого ничего не осталось. stlw писал(а): И еще - movdqa сделает очень еффектный #GP если EDI не выровнен на 16 байт. Не вижу проверки в коде Я проверку делаю. В противном случае используется stos. Код: and eax, 0xf
jz use_sse2 |
Автор: | mrlolthe1st [ 05 авг 2018, 03:58 ] |
Заголовок сообщения: | Re: Поддержка SSE2 в эмуляторах |
Зачем SSE2? Я использую просто SSE для копирования памяти, memset и тд, работает куда быстрее чем rep mowsb, для movsb/w/d требуется даже больше времени, чем на loop. Сортировал по возрастанию скорости работы. Главное - сбросить флаг D(irection) командой cld. 1. Тупой метод Код: mov ecx, count rep mowsb 2. Более интеллектуальный Код: mov ecx, count shr ecx, 2 rep movsd mov ecx, count and ecx, 0x3 rep movsb 3. Еще более Код: mov ecx, count shr ecx,2 q: movsd dec ecx jnz q mov ecx, count q2: movsb dec ecx jnz q2 4. Еще более Код: void memcpy(unsigned char * s, unsigned char * d, size_t count) {
__asm__("pusha\n\ mov %2,%%ecx\n\ mov %0,%%esi\n\ mov %1,%%edi\n\ test %%ecx,%%ecx\n\ jz zr\n\ memcpySSE:\ movups (%%esi),%%xmm0 \n\ movups %%xmm0,(%%edi) \n\ add $16, %%esi \n\ add $16, %%edi \n\ dec %%ecx \n\ test %%ecx,%%ecx \n\ jnz memcpySSE \n\ zr: \n\ mov %3, %%ecx \n\ test %%ecx,%%ecx \n\ jz send \n\ memcpySSE_1: \ movsb \n\ dec %%ecx \n\ jnz memcpySSE_1 \n\ send: \ popa" ::"r"(s),"r"(d),"r"(count>>4),"r"(count%16)); } |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |