· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.ASSEMBLER —› Сложение очень-очень длинных чисел

<< . 1 . 2 . 3 . 4 . 5 . 6 . 7 . 8 . 9 . 10 . >>

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


Дата: Окт 30, 2004 10:30:42 · Поправил: leo

"Уговорить" P4-1800 15.2.4 выполнять ADC с перекрытием никак не удается.
При развороте большую часть MOV удается распараллелить с ADC, но сами ADC все равно выполняются последовательно, поэтому общую задержку менее ~1050-1100 тиков получить не удается (т.е. ~8 тактов на сложение = latency ADC). Перепробовал все варианты расположения mov и, ради экперимента, вообще закоментировал все mov, оставив одни ADC - нет не желают они перекрываться и все тут. Видимо Intel-ы чего-то напутали: или в мануале опечатка или блок динамического исполнения "недоделанный". В мануале для ADC throughput = 3, а на деле получается ~8 = latency. (По определению: "Throughput - the number of clock cycles required to wait before the issue ports are free to accept the same instruction again").

Вывод простой: ADC на P4 - это "тормозной отстой" :)


Дата: Ноя 2, 2004 16:44:16

leo > "Уговорить" P4-1800 15.2.4 выполнять ADC с перекрытием никак не удается."
Увы, на мои уговоры процессор также не поддался. Похоже, что тема себя исчерпала и пора мне подводить итоги. Через пару дней сделаю :)


Дата: Ноя 3, 2004 08:59:52

leo > „Видимо Intel-ы чего-то напутали: или в мануале опечатка или блок динамического исполнения "недоделанный". В мануале для ADC throughput = 3, а на деле получается ~8 = latency.“

Да зачем intel'у путать в доках, причем от версии к версии..
Есть такое понятие, как заваисимость по данным.
Пока данные для операции не готовы, выполняться она не будет.
ADC ждёт результатов выполнения предыдущего ADC.
Именно поэтому в данном случае и получается, что throughput не 3, а "как бы" 8.


Дата: Ноя 3, 2004 14:00:52 · Поправил: leo

S_T_A_S_
Насчет зависимости я конечно понимаю и не зря подчеркнул цитату "to accept the same instruction again". Вопрос в том, как понимать "the same" - как "точно такую же" или "похожую, аналогичную". Последовательные инструкции ADC всегда являются зависимыми и если вторая вынуждена всегда ждать первую, то интелам не стоило бы морочить людям голову и указывть throughput = 3 вместо 8, если под "the same" в данном случае имеется ввиду такая же ADC. Если же под throughput понимается просто освобождение порта для принятия другой инструкции - тогда понятно.

И потом, у меня теплилась надежда на то, что все-таки флаг CF играет особую роль, т.к. используется в ADC\SBB и поэтому устаналивается не только в EFLAGS, откуда его потом долго извлекать (сутя по latency ADC,SBB,SETC), а еще и в некий дополнительный бит или темп-регистр. И тогда, если бы P4 был бы "поумнее", вторая ADC могла бы работать быстрее, беря на лету это значение CF не связываясь с EFLAGS. Но к сожалению, это оказалось бесплодными фантазиями.

PS: Посмотрел, что пишет Агнер Фог (pentopt.pdf), так у него для ADC на P4 приводится throughput = latency = 6 для r,r и 8 для r,m. Все ясно и понятно.


Дата: Ноя 4, 2004 00:00:34

leo
Возможно если между первой ADC и второй вставить инитрукцию, которая "разобьет" зависимость между ними, то тогда и только тогда будет throughput = 3?


Дата: Ноя 4, 2004 09:13:44

leo > „Насчет зависимости я конечно понимаю и не зря подчеркнул цитату "to accept the same instruction again". Вопрос в том, как понимать "the same" - как "точно такую же" или "похожую, аналогичную".“
     „Для неведомого все имена, что одно.
     Видеть в чудесном чудесное - вот ключ ко всем тайнам мира.“


> „Посмотрел, что пишет Агнер Фог (pentopt.pdf), так у него для ADC на P4 приводится throughput = latency = 6 для r,r и 8 для r,m. Все ясно и понятно.“

Как-то один очень уважаемый мною человек сказал мне, что athlon способен выполнить 9 nop за такт.
Только по прошествии большого количества времени я (надеюсь) понял, что он хотел мне сказать.

В 2х словах смысл такой:
Существует как непроверенная информация, так и официальная документация!


Дата: Ноя 4, 2004 09:36:29 · Поправил: leo

S_T_A_S_
Все-таки я не понимаю, что ты хочешь сказать. Я вроде бы свою мысль уже пояснил: если 3 - это время освобождения порта для приема (не обязательно начала исполнения) следующей инструкции, то ясно. НО если следующая ADC всегда вынуждена ждать завершения предыдущей ADC, то реальный темп выполнения последовательных ADC будет >= 8 тактов. Правильно ?

Что касается уважаемого Агнера, то он приводит другую, более понятную величину reciprocal throughput:
This value indicates the number of clock cycles from the execution of an instruction begins to a subsequent independent instruction can begin to execute in the same execution subunit. Как видим, эта величина больше соответствует тому, что мы хотим знать об ADC, чем величина throughput приводимая Intel.


Дата: Ноя 4, 2004 10:29:01 · Поправил: semen

Хмм.. И все-же разбивание зависимости влияет:

RDTSCTimer timer;
timer.StartCount();
__asm
{
mov ecx, 100000
mov ebx, 1
xor eax, eax
.align 16
loop_:
adc eax, ebx
adc eax, ebx
adc eax, ebx
adc eax, ebx
adc eax, ebx
adc eax, ebx
adc eax, ebx
adc eax, ebx
adc eax, ebx
adc eax, ebx
adc eax, ebx
adc eax, ebx
adc eax, ebx
adc eax, ebx
adc eax, ebx
adc eax, ebx
dec ecx
jnz loop_
}
__int64 time = timer.GetTime();
printf("processor ticks without break: %I64i\n", time);

timer.StartCount();
__asm
{
mov ecx, 100000
mov ebx, 1
xor eax, eax
.align 16
loop2_:
mov edx, 0xffffffff
adc eax, ebx
shl edx, 1
adc eax, ebx
shl edx, 1
adc eax, ebx
shl edx, 1
adc eax, ebx
shl edx, 1
adc eax, ebx
shl edx, 1
adc eax, ebx
shl edx, 1
adc eax, ebx
shl edx, 1
adc eax, ebx
shl edx, 1
adc eax, ebx
shl edx, 1
adc eax, ebx
shl edx, 1
adc eax, ebx
shl edx, 1
adc eax, ebx
shl edx, 1
adc eax, ebx
shl edx, 1
adc eax, ebx
shl edx, 1
adc eax, ebx
shl edx, 1
adc eax, ebx
dec ecx
jnz loop2_
}
time = timer.GetTime();
printf("processor ticks with break: %I64i\n", time);

Что выдает на моем P4Mobile-1700 F15 M2 S4:
processor ticks without break: 11953340
processor ticks with break: 9814656

Т.е. с разбиением 6 тиков на adc и сдвиг

на P4-2800 F15 M2 S9:
processor ticks without break: 11448676
processor ticks with break: 6386308

Т.е. с разбиением 4 тика на adc и сдвиг

на Dual P2-300 F6 M3 S3:
processor ticks without break: 3921358
processor ticks with break: 4022432
- 2.5 тика


Дата: Ноя 4, 2004 11:07:41 · Поправил: leo

semen
Да, результат интересный в познавательном плане.
Вот только перенос при такой разбивке теряется и к задаче сложения это видимо никак не "прицепишь".

PS: С P2,P3 (Family 6) все понятно, там и ADC 2-3 такта.


Дата: Ноя 4, 2004 11:59:43

leo > „если следующая ADC всегда вынуждена ждать завершения предыдущей ADC, то реальный темп выполнения последовательных ADC будет >= 8 тактов.“

Ну почему же всегда? CF можно учитывать другим способом, и добавить инструкции убирающие зависимость по данным (см. пример semenа)


> „эта величина больше соответствует тому, что мы хотим знать об ADC, чем величина throughput приводимая Intel.“

Вот здесь ключевое слово "хотим". Такая уж психология у людей - из 2х вариантов ответа выбирается не тот, который правильный, а тот что по душе. Захотим - у нас и the same будет значить "похожую, аналогичную" :)


> „Вот только перенос при такой разбивке теряется и к задаче сложения это видимо никак не "прицепишь".“

А это и не удивительно, т.к. задача до сих пор толком не поставлена - не понятно в каком формате хранятся числа.
Если же знать формат, знать о (не)возможности складывать 2 пары чисел параллельно - тогда можно перейти от слов "видимо" к "очевидно"..

ЗЫ: про "любой формат" мне можно не напоминать, я пытался делать предположения, а они оказались частным случаем. А как можно сочинять свой формат не зная толком как он потом будет использоваться, не пойму :(


Дата: Ноя 4, 2004 13:55:37 · Поправил: leo

S_T_A_S_
Ты все о своем. Почему "обычные"-то числа нельзя складывать. Есть же int16, int32, int64, так почему бы и int512 не использовать. Gray прав - вроде бы все уже выжали из "обычного" сложения. Если интересно, то можно и другие форматы рассмотреть или параллельное сложение двух пар чисел.

Хотя до кучи вот еще вариантик - с использованием циклического сдвига RCL, который работает несколько быстрее SETC:
	shr ecx,2
	xor edx,edx
	xor ebp,ebp
align 16
@@loop:
	mov eax,[esi]
	mov edi,[ebx]
	or  edx,ebp
	add edi,eax
	rcl ebp,1
	and edx,1
	add edi,edx
	mov [ebx],edi
	rcl edx,1
	.............
        ;разворот цикла на 4: +3 повтора со смещением 4, 8 и 12
	.............
	lea esi,[esi+16] ;add esi,16 - без разницы
	lea ebx,[ebx+16]
	sub ecx,1        ;dec ecx - хуже
	jnz @@loop}
Также возможна "статистическая" модификация с заменой rcl edx,1 на jc:
	mov eax,[esi]
	mov edi,[ebx]
	add edi,eax
	rcl ebp,1
	and edx,1
	add edi,edx
	mov [ebx],edi
	jc  @@carry1
	mov edx,ebp
@@carry1:
Результаты на P4-1800 (15.2.7):
Gray.............1428
leo_rcl..........1008
leo_rcl_jc.......816,900,828,828... - разные цифры для проходов 2,3 и 4-8 для данных Data1 Gray
...............................видимо из-за наличия переходов по jc


Дата: Ноя 4, 2004 13:57:47 · Поправил: semen

leo
„Да, результат интересный в познавательном плане.
Вот только перенос при такой разбивке теряется и к задаче сложения это видимо никак не "прицепишь".

PS: С P2,P3 (Family 6) все понятно, там и ADC 2-3 такта.“


Ну я о познавательном плане и заботился... к тому что интел не соврал про throughput = 3... и если в этой задаче не получится использовать быстрый adc - в другой получится...


Дата: Ноя 4, 2004 14:10:10

semen
Ясно, спасибо


Дата: Ноя 7, 2004 10:55:05 · Поправил: leo

Учел замечания semen и S_T_A_S_ по возможности перекрытия ADC за счет добавления инструкций, учитывающих перенос и устраняющих зависимость ADC. На P4 15.2.7 получаются превосходные результаты при развороте цикла на 4 сложения:
macro leo_ADC_fast4{
	shr ecx,2
	clc
align 16
.loop:
	mov     eax,[esi]
	mov     edi,[ebx]
	mov     ebp,eax
	adc     eax,edi         ;ADC[0] <--- EAX
	;устраняем зависимость
	add     ebp,edi         ;"основной" перенос
	inc     ebp             ;контроль "редкого" случая x[i]+y[i] = $FFFFFFFF
	jz      .carry1
.ret1:
	mov     edx,[esi+4]
	mov     edi,[ebx+4]
	mov     ebp,edx
	adc     edx,edi         ;ADC[4] <--- EDX
	;устраняем зависимость
	add     ebp,edi
	inc     ebp
	jz      .carry2
.ret2:
	mov     [ebx],eax       ;---> MOV[0] EAX
	mov     eax,[esi+8]
	mov     edi,[ebx+8]
	mov     ebp,eax
	adc     eax,edi         ;ADC[8] <--- EAX
	;устраняем зависимость
	add     ebp,edi
	inc     ebp
	jz      .carry3
.ret3:
	mov     [ebx+4],edx     ;---> MOV[4] EDX
	mov     edx,[esi+12]
	mov     edi,[ebx+12]
	adc     edx,edi         ;ADC[12] <--- EDX
	;здесь остается ждать результата
	mov     [ebx+8],eax     ;---> MOV[8] EAX
	mov     [ebx+12],edx    ;---> MOV[12] EDX

	lea     esi,[esi+16]
	lea     ebx,[ebx+16]
	dec     ecx
	jnz     .loop

	jmp     .end
.carry1:
	;--- коррекция CF ---
	;здесь ebp = x+y+1 = 0 => либо eax = 0 (был перенос и будет),
	;                         либо eax = -1 = $FFFFFFFF (не было переноса и не будет)
	cmp eax,-1 ;CF установится если eax = 0, т.е. eax ниже $FFFFFFFF
	jmp .ret1
.carry2:
	cmp edx,-1
	jmp .ret2
.carry3:
	cmp eax,-1
	jmp .ret3
.end:
};==========================================
Можно учет переноса по JZ вставить в тело цикла, но при этом результаты получаются несколько хуже
	add     ebp,edi
	inc     ebp
	;db	$3E     ;префикс выполнения прыжка, при нескольких проходах ничего не дает
	jnz     .ret1
	cmp     eax,-1
.ret1:
	.......
Вот результаты на P4-1800 (15.2.7)
Gray...............1428
Gray_SSE2...........940
leo_JZ..............832  
leo_ADC_fast4......732,776,728,676,676... ;рез-ты проходов 2,3.. по Data1 Gray
leo_ADC_fast4jnz...756,772,772,692,692... ;- " -
Кстати на P4 15.2.4 этот же код дает заметно худшие результаты, а предварительный разворот на 8 сложений тоже получается чуть хуже => остаются какие-то зависимости от расположения инструкций, длины тела цикла и т.п.


Дата: Ноя 9, 2004 12:05:03

leo, ты меня поражаешь! Я уж думал, что все из процессора уже выжали, а ты своим leo_ADC_fast4 показал, что сие вовсе не так.

leo >"На P4 15.2.7 получаются превосходные результаты при развороте цикла на 4 сложения..."

На P4 15.2.9 результаты столь же превосходны, завтра протестирую на других процессорах.

P.S. Воистину nop так же неисчерпаем как и pop :)

<< . 1 . 2 . 3 . 4 . 5 . 6 . 7 . 8 . 9 . 10 . >>


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