С Наступившим! Подскажите, можно ли как-нибудь выделить память под Win32 сразу с необходимым выравниванием? (на 4 или 16 байт). В голову приходит только выделять на 15 байт больше (для выравнивания на 16), а затем уже корректировать смещение для реального начала буфера. Может все-таки есть способ получше?
VirtualAlloc() / HeapAlloc() - выделяют память начиная с адреса, выровненного на 0x1000 т.е. и 4 и 0x10 включительно. С выравниванием не парься )))))
Magnum Просто мне нужно копировать достаточно большие блоки (~1МБ в обычном состоянии). Причем очень быстро и часто. Вот и хотел выделять память с выравниванием для нормальной работы. Great Буду пробовать VirtualAlloc.
VirtualAlloc однозначно. Ээ а хип аллок то с какой радости? Если я выделяю в куче допустим 20 байт. Или ты про то, если размер выделения кратен странице? Но в любом случае незачем засирать кучу подобными выделениями, она не для этого предназначена..
P.S. Вопрос не совсем по теме, но не хочу засорять форум лишними ветками. Вот код копирования блока памяти из src в dst длиной в u32Len байт на MMX. Большинство вызовов - для блоков в пределах 1МБ с размером кратным 4 или даже 16. Можно его как-нибудь ускорить/оптимизировать/доработать? (разговор ТОЛЬКО о MMX) Код (Text): void copyMemoryMMX( VU8 src, VU8 dst, U32 u32Len ) { if (!u32Len) return; // тут сохраняю MMX регистры DWORD tmp[2*8]; __asm { pushad mov esi, src mov edi, dst mov eax, u32Len // может стоит вставить здесь проверку на < 64 и просто rep movsb? mov edx, 64 // приращение mov ecx, eax shr ecx, 6 and eax, 63 // сохраняю MMX регистры movq qword ptr [tmp], mm0 movq qword ptr [tmp+8], mm1 movq qword ptr [tmp+16], mm2 movq qword ptr [tmp+24], mm3 movq qword ptr [tmp+32], mm4 movq qword ptr [tmp+40], mm5 movq qword ptr [tmp+48], mm6 movq qword ptr [tmp+56], mm7 test ecx, ecx jz _Below64 // цикл копирования по 64 байта _copy_loop_64: movq mm0, qword ptr [esi] movq mm1, qword ptr [esi+8] movq mm2, qword ptr [esi+16] movq mm3, qword ptr [esi+24] movq mm4, qword ptr [esi+32] movq mm5, qword ptr [esi+40] movq mm6, qword ptr [esi+48] movq mm7, qword ptr [esi+56] movq qword ptr [edi], mm0 movq qword ptr [edi+8], mm1 movq qword ptr [edi+16], mm2 movq qword ptr [edi+24], mm3 movq qword ptr [edi+32], mm4 movq qword ptr [edi+40], mm5 movq qword ptr [edi+48], mm6 movq qword ptr [edi+56], mm7 add esi, edx add edi, edx dec ecx jnz _copy_loop_64 _Below64: // меньше 64 байт. длина в EAX. в ECX содержится 0. shr edx, 1 // edx == 32 cmp eax, edx jb _Below32 // больше 32 но меньше 64 байт - можно скопировать еще 32 movq mm0, qword ptr [esi] movq mm1, qword ptr [esi+8] movq mm2, qword ptr [esi+16] movq mm3, qword ptr [esi+24] movq qword ptr [edi], mm0 movq qword ptr [edi+8], mm1 movq qword ptr [edi+16], mm2 movq qword ptr [edi+24], mm3 add esi, edx add edi, edx sub eax, edx _Below32: // меньше 32 байт shr edx, 1 // edx == 16 cmp eax, edx jb _Below16 // больше 16 но меньше 32 байт - можно скопировать еще 16 movq mm0, qword ptr [esi] movq mm1, qword ptr [esi+8] movq qword ptr [edi], mm0 movq qword ptr [edi+8], mm1 add esi, edx add edi, edx sub eax, edx _Below16: // меньше 16 байт shr edx, 1 // edx == 16 cmp eax, edx jb _Below8 // больше 8 но меньше 16 байт - можно скопировать еще 8 movq mm0, qword ptr [esi] movq qword ptr [edi], mm0 add esi, edx add edi, edx sub eax, edx _Below8: // меньше 8 байт. не буду извращаться - просто rep movsb test eax, eax jz _zero xchg eax, ecx cld rep movsb _zero: // восстанавливаю MMX регистры movq mm0, qword ptr [tmp] movq mm1, qword ptr [tmp+8] movq mm2, qword ptr [tmp+16] movq mm3, qword ptr [tmp+24] movq mm4, qword ptr [tmp+32] movq mm5, qword ptr [tmp+40] movq mm6, qword ptr [tmp+48] movq mm7, qword ptr [tmp+56] popad } }
Xerx Глянь в Optimizing memory bandwidth (или Block prefetch paper) по поводу кода копирования с помощью mmx.
IceStudent Как раз то, что надо! Я нашел урезанный вариант Block prefetch paper и по нему и сделал... Но еще можно сильно улучшить. Спасибо большое!