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

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

. 1 . 2 . 3 . >>

Посл.отвђт Сообщен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 или больше.

. 1 . 2 . 3 . >>


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