Здравствуйте, cpp, Вы писали:
cpp>Здравствуйте, Дубров Иван Сергеевич, Вы писали:
ДИС>>Где-то я видел (AMD-шная статья кажется) кусок кода для быстрого копирования куска памяти (с использованием кэша, инструкций MMX и прочей фигни). При этом копирование REP MOVSD оказывается гораздо медленнее. Так что возможно есть способ гораздо быстрее REP STOSD.
cpp>(bandwidth: ~1630 Mbytes/sec)
cpp>cpp>#define CACHEBLOCK 400h // QWORDs in a block (8K bytes)
cpp> mov esi, [src] // source array
cpp> mov edi, [dst] // destination array
cpp> mov ecx, [len] // total number of QWORDS (8 bytes)
cpp> // (assumes len / CACHEBLOCK = integer)
cpp> lea esi, [esi+ecx*8]
cpp> lea edi, [edi+ecx*8]
cpp> neg ecx
cpp> emms
cpp>mainloop:
cpp> mov eax, CACHEBLOCK / 16 // note: prefetch loop is unrolled 2X
cpp>prefetchloop:
cpp> mov ebx, [esi+ecx*8] // Read one address in line,
cpp> mov ebx, [esi+ecx*8+64]// and one address in the next.
cpp> add ecx, 16 // add 16 QWORDS, = 2 64-byte cache lines
cpp> dec eax
cpp> jnz prefetchloop
cpp> sub ecx, CACHEBLOCK
cpp> mov eax, CACHEBLOCK / 8
cpp>writeloop:
cpp> movq mm0, qword ptr [esi+ecx*8]
cpp> .
cpp> .
cpp> movq mm7, qword ptr [esi+ecx*8+56]
cpp> movntq qword ptr [edi+ecx*8], mm0
cpp> .
cpp> .
cpp> movntq qword ptr [edi+ecx*8+56], mm7
cpp> add ecx, 8
cpp> dec eax
cpp> jnz writeloop
cpp> or ecx, ecx
cpp> jnz mainloop
cpp> sfence
cpp> emms
cpp>
вспоминается, как на z80 народ память забивал нулями с помощью стека. Ставится указатель стека на конец нужной области и push a, push a, push a ....
Самый быстрый метод был. Быстрее народ не придумал
для 486 самый быстрый метод использовал регистры сопроцессора.
А под Linux-ом, ядро при старте пробует десколько методов копирования памяти, выбирает самый быстрый и дальше внутри ядра только этим методом и пользуется
В общем извращаться можно долго и сильно !!!
... << RSDN@Home 1.0 beta 3 >>