|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Ноя 10, 2003 15:01:18 Ужас и страх.
;===================================================================== ============
.586
.model flat
option casemap :none ; case sensitive
; ###################################################################### ###
include mem.inc
; ###################################################################### ###
.code
;///////////////////////////////////////////////////////////////////// /////
;///////////////////////////////////////////////////////////////////// /////
mem@copy proc
comment /***************************
DPN: Функция копирует с точностью до байт
область памяти источника в память приёмника
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
IN:
esi - источник
edi - приёмник
ecx - обём памяти для пересылки
OUT:
ecx - число нескопированных байт
************************************/
.data
lshift_tbl dd offset shift_loop_3 ;; 1
dd offset shift_loop_2 ;; 2
dd offset shift_loop_1 ;; 3
rshift_tbl dd offset shift_loop_1 ;; 1
dd offset shift_loop_2 ;; 2
dd offset shift_loop_3 ;; 3
.code
;; Проверка на размер ecx
;; Если он меньше 32, то нет смысла что либо делать
cmp ecx,32
mov eax,esi
jbe short small_copy
;; Учёт направления сдвигов
;; Ниже показана схема, согласно которой
;; осуществляются сдвиги
;; [|___|___|___|___|___|___|___|___|___|___|]
;; [======000000000000=======================]
;; [=====================1111111111==========]
;; [|===|===|===|===|===|xx_|===|===|===|===|]
;; сдвигает значение влево на 1
;; если невыровненость источника меньше чем у приёмника
;; [|___|___|___|___|___|___|___|___|___|___|]
;; [======000000000000=======================]
;; [=======================11111111==========]
;; [|===|===|===|===|===|==xx===|===|===|===|]
;; Здесь он сдвигает значение вправо на 1
;; если невыровненость источника больше чем у приёмника
mov edx,edi
and eax,11b
push edi
and edx,11b
push esi
sub eax,edx
mov edx,offset lshift_tbl
ja short @F
neg eax ;; eax = |eax|
mov edx,offset rshift_tbl
@@:
;; Если значения невыровненности не совпадают
jnz short not_coincidence
;; Если младшие биты eax == 0, это значит,
;; что участки памяти совпадают между собой
;; и даже если они не выровнены,
;; то они невыровнены на одну и ту же самую величину, что крайне удобно
mov eax,esi
and eax,11b
mov edx,ecx
mov ecx,4
sub ecx,eax
sub edx,ecx
rep movsb
mov ecx,edx
loop_copy:
and edx,11b
shr ecx,2
rep movsd
;; Если ещё не всё скопировано, тогда
mov ecx,edx
rep movsb
pop esi
pop edi
ret
small_copy:
add ecx,4
rep movsb
pop esi
pop edi
ret
not_coincidence:
;; Если мы пришли в эту точку функции,
;; значит:
;; 1. Значение операндов не выровнены
;; 2. Они не совпадают
;; В eax находится степень несовпадения
;;
;; Поэтому мы будем употреблять сдвиги, для того,
;; чтобы избежать обращений к невыровненым данным
;; Приводим значение edi к выровненому
;; И кропируем часть байт из источника
lea eax,[edx+eax*4-4]
push eax
mov edx,ecx
mov ecx,edi
mov eax,4
and ecx,11b
sub edx,eax
sub eax,ecx
sub edx,eax
mov ecx,eax
rep movsb
pop eax
mov ecx,edx
and esi,not 11b
mov edx,[esi]
add esi,4
jmp dword ptr [eax]
align 16
shift_loop_1:
@@:
shr edx,24 ;; 1
mov eax,[esi]
add esi,4 ;; 2
mov [edi],edx
mov edx,eax ;; 3
shl eax,8
or [edi],eax ;; 4
add edi,4
sub ecx,4 ;; 5
ja short @B
jmp short small_copy
align 16
shift_loop_2:
@@:
shr edx,16
mov eax,[esi]
add esi,4
mov [edi],edx
mov edx,eax
shl eax,16
or [edi],eax
add edi,4
sub ecx,4
ja short @B
jmp short small_copy
align 16
shift_loop_3:
@@:
shr edx,8
mov eax,[esi]
add esi,4
mov [edi],edx
mov edx,eax
shl eax,24
or [edi],eax
add edi,4
sub ecx,4
ja short @B
jmp small_copy
mem@copy endp
|
|
|
Дата: Ноя 10, 2003 18:25:41 А откуда собственно такой код? |
|
|
Дата: Ноя 10, 2003 19:45:34 AsmGuru62 Откуда ? от меня понятно. |
|
|
Дата: Ноя 10, 2003 19:48:34 Комментарии Это код копирования байт. Который копирует невыровненные блоки при помощи сдвигов. |
|
|
Дата: Ноя 10, 2003 23:13:26 А почему нельзя простым MOVSD, а остаток - MOVSB? Или я (снова!) чего-то недопонял?.. |
|
|
Дата: Ноя 11, 2003 04:26:45 AsmGuru62 movsd хороша, если адрес приемника и источника выровнен по границе двойного слова. |
|
|
Дата: Ноя 11, 2003 05:18:52 · Поправил: Grenader Edmond Вот прочитаешь такое - и мозги разу рабоать начинают в удвоенном темпе :) Спасибо за интересный пример. |
|
|
Дата: Ноя 11, 2003 07:16:33 · Поправил: S_T_A_S_ Edmond, Извините, пожалуйста, может я просто не понял где это можно применить? Почему не проще копировать выровненные данные через MMX/SSE? Вроде бы памяти у всех валом. А вот скорость у нее хромает. |
|
|
Дата: Ноя 11, 2003 13:36:37 S_T_A_S_ Представь, что тебе нужно дописать одну строку в конец другой ... |
|
|
Дата: Ноя 11, 2003 13:54:23 All Погодите!!! Ещё никто не доказал, что этот код эффективен!!! Крис молчит :)) У меня нет времени его протестировать. Там вот значение 32. Может быть 64 лучше? -------------------------- Насчёт MMX Я вижу уже в уме супер релиз на MMX Ну просто перед глазами. Алгоритм тот же что и уменя. Но кода меньше в 4 раза + скорость. Эх, нет времени :((( А как хочется, чтобы картинка ожила. |
|
|
Дата: Ноя 11, 2003 13:56:33 AsmGuru62 А почему нельзя простым MOVSD, а остаток - MOVSB? Или я (снова!) чего-то недопонял?.. Мне часто говорят, что я "псих комментария" :)) Слишком сильно комментирую программы. Надеюсь это так :) |
|
|
Дата: Ноя 11, 2003 14:13:52 Привет, Эдмонд. Идеальное применение для soft pipe со спекуляцией. А выравнивание незаменимо, т. к. невыровненная ссылка вообще не пройдет. |
|
|
Дата: Ноя 11, 2003 19:19:49 А в чем проблема-то ? Я вчера потестил скорость копирования простейшим циклом - _loop: mov eax,[esi]; mov [edi],eax; add esi,4; add edi,4; dec ecx; jnz _loop; И на своем Атлоне никакого падения производительности в зависимости от выравнивания src/dst не заметил. Скорость зависит от того находятся ли один/оба src/dst в кеше/памяти. Соответственно зависит от размера блока (большие целиком в кеш не помещаются, у маленьких накладные расходы на измерение) А от выравнивания - ну практически никак :) Стоит-ли огород городить? Или я чего-то опять не понимаю ? |
|
|
Дата: Ноя 11, 2003 19:35:09 Shur Код ниже у меня на Атлоне занимает 2 такта (метки выровнены на 4), если коментарии убрать - 7. Имхо, есть разница lea esi, d1 ;inc esi lea edi, d2 ;inc edi mov eax, [esi] mov [edi], eax |
|
|
Дата: Ноя 11, 2003 21:05:02 Дык.. если копировать 4 байта, тогда конечно(ну и не 2, а как минимум 3 - там цепочка зависимости из 3-х команд). Но вряд-ли стоит изобретать такую функцию для копирования 4-х байт. А ты померяй скажем блок ~2k или больше. |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.038 |