· Начало · Статистика · WASM.RU · Noir.Ru ·

 WASM Phorum (Оффлайн - 24.11.2003) —› WASM.A&O —› Копирование байт для извращенцев

<< . 1 . 2 . 3 .

Посл.отвђт Сообщен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 в начале убрал %)))
Спасибо. Это другое дело...

<< . 1 . 2 . 3 .


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.099