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

 WASM Phorum (Оффлайн - 24.11.2003) —› WASM.A&O —› Оптимизация игры жизнь

Посл.отвђт Сообщенiе


Дата: Сен 11, 2003 05:48:34

Кто-нибудь этим занимался?
Для процессора Atlon1900+ у меня получается 5-6 тактов на точку, если не использовать MMX. А при использовании MMX:
2 такта на точку для поля на 128 миллионов точек.
И примерно 0,5 такта на точку для поля 10-50 тысяч точек.
Похоже проблема в том, что четыре комманды movq собрались в одном месте, а разнести их не получатся 8(


Дата: Сен 11, 2003 11:58:25

Black_mirror
Исходники в студию!!!


Дата: Сен 12, 2003 15:20:45

Edmond
align 32
fast_life:;(start +4, end +8, delta +12)
	mov eax,[esp+8]
	mov edx,[esp+12]
	lea ebx,[eax+edx]
	lea ecx,[eax+edx*2]
	mov edx,[esp+4]
	sub edx,eax
	movq mm6,[eax+edx]
	movq mm5,[ecx+edx]
	movq mm7,[ebx+edx]
    .l0:;mm5=next_line,mm6=prev_line,mm7=cur_line
	movq mm0,mm5
	movq mm2,mm7
	add edx,7
	pxor mm0,mm6	
	pand mm5,mm6	;5:0=m:l
	pand mm2,mm0

	pxor mm0,mm7	
	movq mm3,mm0
	por mm2,mm5	;2:0=m:l
	psrlq mm0,1	;0=ll
	movq mm6,[eax+edx];for next step
	movq mm1,mm3

	pxor mm3,mm0
	pand mm1,mm0	;1:3=m:l,2=mmm
	psrlq mm0,1	;0=l
	movq mm4,mm3
	pand mm3,mm0
	pxor mm0,mm4	

	por mm1,mm3	;1:0=m:l,2=mmm
	movq mm4,mm2
	movq mm3,mm1
	movq mm5,[ecx+edx];for next step
;	prefetcht0 [ebx+edx+7]
	pxor mm1,mm2
	psrlq mm4,1	;4=mm

	pand mm2,mm3	;2:1:0=h:m:l
	movq mm3,mm1	
	pxor mm1,mm4	
	pand mm3,mm4
	psrlq mm4,1	;4=m
	pxor mm2,mm3	;2:1:0=h:m:l

	movq mm3,mm1
	pand mm3,mm4
	psrlq mm7,1
	pxor mm1,mm4
	movq mm4,[ebx+edx];for next step
	pxor mm2,mm3	;2:1:0=h:m:l

	movq mm3,mm0
	por mm0,mm1	;d1|d0
	pand mm3,mm1	;d1&d0
	pand mm7,mm2	;s&d2
	pandn mm2,mm3	;~d2&d1&d0
	pandn mm0,mm7	;s&d2&~(d1|d0)

	movq mm7,mm4
	por mm0,mm2
	movq [eax+edx-7],mm0
	js .l0
	ret 12

;формат массива для данной процедуры:
;width=m,height=n
;delta=(m+2+7)/8	
;size=delta*(n+2)+7
;end=start+delta*n
;перед вызовом процедуры нужно сделать так чтобы
;bit[m]=bit[0],bit[m+1]=bit[1], для всех строк
;и line[n] = line[0], line[n+1] = line[1]
;start 	rb delta	//line 0
;	rb delta	//line 1
;	...
;	rb delta	//line n-1
;end	rb delta	//line n 
;	rb delta	//line n+1
;	rb 7
;
;после вызова процедуры массив окажется смещенным на один бит по диагонали
;line[i].bit[j]=line[i+1].bit[j+1]
;например:
;исходный массив:
;	line0 = 00000000b,00000000b, ...
;	line1 = 10000100b,00000001b, ...
;	line2 = 01000100b,00110010b, ...
;	line3 = 10000100b,00110001b, ...
;	line4 = 00000000b,00000000b, ...
;	            ...
;результирующий массив:
;	line0 = 11000000b,00000000b, ...
;	line1 = 00100111b,00011001b, ...
;	line2 = 11000000b,00011000b, ...
;	            ...
;
;тестирование производительности
;Система AthlonXP1900+,DDR2700,системная шина 133
; 	 размер,байт  тактов всего,hex    
;	size	delta	min	max	тактов на точку
;	4K	256	36DA	373C	      0.43 xe-xe
;	64K	256	36AB4	37537	      0.43
;	64K	4K	378A4	4EDE4       0.45-0.6
;	1M	256	4A611C	553400	    0.6-0.65
;	1M	4K	464FE3	4DEB64	    0.55-0.6
;	1M	64K	56A6B3	D6DB23	     0.7-1.7
;	16M	256	4BBC935 507AE92       0.6
;	16M	4K	478BEC9 4F7EAA5     0.55-0.6  
;	16M	64K	5497633	D3CB041     0.65-1.7
;	16M	1M	61F08BC	C0B03DF	    0.8-1.5


Если кто поделится соображениями или замечаниями по поводу этого кода, особенно о том как это еще соптимизировать, буду очень рад. Ну а также хотелось бы знать на сколько быстрее это работает на SSE2. Чтобы переделать этот код под SSE2, нужно только названия регистров заменить и число 7 на 15.


Дата: Сен 12, 2003 20:16:37

Вот внедрил сей код в программу.

И еще у меня есть два вопроса: есть переменная, к которой не должны получать доступ одновременно два потока. Что здесь нужно ставить: семафор или что-то другое? И если поток находится в критической секции может он быть завершен другим потоком?



_1667312850__life.zip


Дата: Сен 12, 2003 20:23:19

Black_mirror
Намёк

xchg eax,flag


Дата: Сен 13, 2003 00:49:34

Edmond
Спасибо.

Мое решение выглядит немного иначе:

buf0 rb size
buf1 rb size
buf2 rb size

bufs dd buf0,buf1,buf2

flag = 80h
freebuf db 0
curbuf db 1
newbuf db 2

первый поток:
ror word [freebuf],8
mov al,[freebuf]
and eax,255-flag
mov eax,[bufs+eax*4];указатель на текущий буфер
чтение
test [curbuf],flag
jnz .ready;если флаг установлен то готов новый массив
ror word [freebuf],8
.ready

второй поток:
;указатель на текущий буфер ему передается при старте
.next:
mov al,[newbuf]
and eax,255-flag
mov eax,[bufs+eax*4];указатель на новый буфер
чтение текущего буфера и запись в новый
or [newbuf],flag
ror word [curbuf],8
jmp next

Нужно будет программу переделать ...


Дата: Сен 13, 2003 14:43:16

Black_mirror
Замечательно.
Но есть одно но.

Мощь вашего расчёта как почувствовать?
Никак :(((

Наживаю GOTO .. и он всё равно инккриментирует заголовок окноа. Это нужно убрать..


Дата: Сен 13, 2003 17:28:40

Заголовок окна это не самое страшное, самое страшное это то, что в моей программе поток завершается/создается заново, выделяется/освобождается память. Вообщем архитектуру программы нужно переделывать, чем в скором времени и займусь.

Вот несколько ссылок:
http://lifegame.virtualave.net
http://elvisti.kiev.ua/skl
http://famlife.narod.ru


Дата: Сен 15, 2003 16:58:51

Black_mirror
Когда то давно я и один чел обсуждали возможную оптимизацию этой штуки.
Думаю позже я расскажу несколько моментов.


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