|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Ноя 13, 2003 20:23:02 Edmond Ты хотел сказать SRC Да вообще-то нет. Через ММХ у меня получается практически одинаково, что src - что dst. If either source or destination cannot be aligned, make the destination aligned and the source misaligned. - но это про строковые команды. Про копирование вообще счас не нашел. Может, вру. S_T_A_S_ На мой взгляд, не совсем корректно измерять скорость копирования в байтах за такт. Потому что скорость ядра на порядок выше скорости доступа к памяти. А вроде как оптимизируем копирование маленьких блоков, целиком помещающихся в L1? Для больших конечно. |
|
|
Дата: Ноя 14, 2003 15:35:56 · Поправил: Edmond Вот классический код. Для блоков до 1 M его достаточно. ;///////////////////////////////////////////////////////////////////// ///// ;///////////////////////////////////////////////////////////////////// ///// mem@copy proc comment /*************************** DPN: Функция копирует с точностью до байт область памяти источника в память приёмника ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IN: esi - источник edi - приёмник ecx - обём памяти для пересылки OUT: ecx - число нескопированных байт ************************************/ .data goto_tbl dd offset goto_0 ;; 0 dd offset goto_3 ;; 1 dd offset goto_2 ;; 2 dd offset goto_1 ;; 3 goto_tbl_tail dd offset goto_0_tail ;; 0 dd offset goto_1_tail ;; 1 dd offset goto_2_tail ;; 2 dd offset goto_3_tail ;; 3 .code mov eax,esi mov edx,4 push edi sub edx,eax push esi and edx,11b ;; Формула edx = (4-(esi and 11b)) and 11b and eax,11b add esi,edx add edi,edx jmp dword ptr goto_tbl[eax*4] goto_3: mov al,[esi-3] dec ecx mov [edi-3],al goto_2: mov al,[esi-2] dec ecx mov [edi-2],al goto_1: mov al,[esi-1] dec ecx mov [edi-1],al goto_0: mov eax,ecx shr ecx,2 and eax,11b rep movsd ;; Если ещё не всё скопировано, тогда jmp dword ptr goto_tbl_tail[eax*4] goto_3_tail: mov al,[esi+3] mov [edi+3],al goto_2_tail: mov al,[esi+2] mov [edi+2],al goto_1_tail: mov al,[esi+1] mov [edi+1],al goto_0_tail: pop esi pop edi ret mem@copy endp ;///////////////////////////////////////////////////////////////////// ///// ;///////////////////////////////////////////////////////////////////// ///// |
|
|
Дата: Ноя 14, 2003 15:36:32;///////////////////////////////////////////////////////////////////// ///// ;///////////////////////////////////////////////////////////////////// ///// mem@move proc comment /*************************** DPN: Функция копирует с точностью до байт перекрываемые области памяти ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IN: esi - источник edi - приёмник ecx - обём памяти для пересылки OUT: ecx - число нескопированных байт ************************************/ .data mgoto_tbl dd offset goto_0 ;; 0 dd offset goto_1 ;; 1 dd offset goto_2 ;; 2 dd offset goto_3 ;; 3 mgoto_tbl_tail dd offset goto_0_tail ;; 0 dd offset goto_1_tail ;; 1 dd offset goto_2_tail ;; 2 dd offset goto_3_tail ;; 3 .code ;; Анализируем то, как устроены данные источника и приёмника cmp esi,edi mov eax,esi ja mem@copy std lea eax,[esi+ecx] push edi push esi lea edi,[edi+ecx-4] mov esi,eax mov edx,ecx and esi,not 11b ;; Выравнивание esi ;; shr ecx,2 and eax,11b sub esi,4 sub edi,eax jmp dword ptr mgoto_tbl[eax*4] goto_3: mov al,[esi+4+2] dec ecx mov [edi+4+2],al goto_2: mov al,[esi+4+1] dec ecx mov [edi+4+1],al goto_1: mov al,[esi+4] dec ecx mov [edi+4],al goto_0: mov eax,ecx shr ecx,2 and eax,11b rep movsd ;; Если ещё не всё скопировано, тогда jmp dword ptr mgoto_tbl_tail[eax*4] goto_3_tail: mov al,[esi+1] mov [edi+1],al goto_2_tail: mov al,[esi+2] mov [edi+2],al goto_1_tail: mov al,[esi+3] mov [edi+3],al goto_0_tail: cld pop esi pop edi ret mem@move endp ;////////////////////////////////////////////////////////////////////////// ;////////////////////////////////////////////////////////////////////////// |
|
|
Дата: Ноя 15, 2003 11:18:58 Edmond Вот классический код. Для блоков до 1 M его достаточно. Мне и rep movsb достаточно. Чего-то я не понял смысл твоего поста :( Типа вопрос закрыт? Или оптимизировать memcpy для маленьких блоков нет смысла? У тебя там как минимум две ошибки: Хвост неправильно копируется - должно быть goto_3_tail: mov al,[esi+2] mov [edi+2],al goto_2_tail: mov al,[esi+1] mov [edi+1],al goto_1_tail: mov al,[esi] mov [edi],al Ну и ecx=0 - вообще балдарис. |
|
|
Дата: Ноя 21, 2003 17:43:40 · Поправил: S_T_A_S_ Shur А вроде как оптимизируем копирование маленьких блоков, целиком помещающихся в L1? Так ведь помещаются они туда все равно из памяти. Это я к тому, что бывает в этом "бутылочном горлышке" самый быстрый алгоритм застревает. Вот на задачах вроде сортировки строк может быть выигрыш (когда они все в кеше) Только надо ли когда и кому сами строки сортировать? Мне и rep movsb достаточно. M$ использует MOVSD+MOVSB, ircc, и все их за это любят :) Если оптимизировать rep movsd в примере Edmond'а посредством MMX + movntq, то будет быстрее. Только появятся goto_63 и кусок этот заметно усложнится. оптимизировать memcpy для маленьких блоков нет смысла? Может я абсолютно не прав, но помоему, разница в скорости копирования между большими и маленькими строками == соотношение "полезных" команд (собственно копирование) к "полезным" + "бесполезным" (доп. вычисления). Учитывая это, наступает момент, когда rep movsb - самый быстрый способ. Поэтому самое главное - что копировать (кстати Вирта я так и не прочитал :( pls комнями не кидайте. т.к. сказано: проще увидеть бревно... |
|
|
Дата: Ноя 22, 2003 12:40:05 Если оптимизировать rep movsd в примере Edmond'а посредством MMX + movntq, то будет быстрее. Кстати я протестил с MMX выйгрыша нет особого. Что до просто rep и та функция, что я привёл.. Разница есть на невыровненных данных, а кроме того, я бы не сказал, что сложность кода велика. Shur Мне и rep movsb достаточно. Чего-то я не понял смысл твоего поста :( Типа вопрос закрыт? Или оптимизировать memcpy для маленьких блоков нет смысла? Ты верно понял. Хвост неправильно копируется - должно быть goto_3_tail: mov al,[esi+2] mov [edi+2],al goto_2_tail: mov al,[esi+1] mov [edi+1],al goto_1_tail: mov al,[esi] mov [edi],al Странно. Смотрю -- ошибка.. а на тестах её не обнаружил. Спасибо!!! Ну и ecx=0 - вообще балдарис. А что ECX??? |
|
|
Дата: Ноя 22, 2003 12:41:45 Поэтому самое главное - что копировать Ну это уж само собой. Мы тут байты копируем :)) |
|
|
Дата: Ноя 22, 2003 18:10:33 А что ECX??? если ecx=0,1,2 и esi не выровнен, то уже в процессе его выравнивания ты можешь скопировать больше байт, чем тебя просили. |
|
|
Дата: Ноя 24, 2003 13:51:28 Shur Угу, пробуем. ecx = 2 ..... Мой процессор выдаёт всё ОК. Я не понял :((( |
|
|
Дата: Ноя 24, 2003 19:59:12 :)))) Разжевываю : пусть например ecx=2, esi=1 ты выравниваешь esi, т.е. копируешь ТРИ байта, в процессе уменьшаешь ecx на ТРИ. когда код доходит до метки goto_0:, esi=4, ecx=-1. Дальше понятно? |
|
|
Дата: Ноя 24, 2003 20:05:21 Shur Вот теперь понятно!!!!!! Ну конечно выходит.. Я ж ему проверку на 32 в начале убрал %))) Спасибо. Это другое дело... |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.099 |