Код (Text): NormVecSSE2_2 proc uses esi edi ecx ebx edx Vector:DWORD, LMass:DWORD .data align 16 tempSSE dq 2 dup (0) .code sub LMass,2 mov eax,LMass mul LMass mov ebx,2 div ebx mov ecx,eax mov esi,Vector lea edi,tempSSE finit fldz fst qword ptr [edi] fst qword ptr [edi+8] LNVSSE_1: movapd xmm0,[esi] mulpd xmm0 ,[esi] addpd xmm0,[edi] movapd [edi],xmm0 add esi,16 loop LNVSSE_1 movapd xmm0,[edi] unpckhpd xmm0,[edi] addsd xmm0,[edi] lea edi,temp movsd [edi],xmm0 cmp edx,0 je NVexit movsd xmm0,qword ptr [esi] mulsd xmm0,[esi] addpd xmm0,[edi] movsd [edi],xmm0 NVexit: ret NormVecSSE2_2 endp
т.е. оформить код как полагается, для этого форум поддерживает bb коды, например [ code ]здесь ваш код[ /code ], причем между [ и ] и словом code пробелы нужно убрать
AndreyATC 1) не понятно что такое LMass и почему число элементов = (LMass-2)^2 2) не понятен финт с fst qword ptr [edi]. Зачем вообще записывать результат в память, если у тебя куча свободных регистров. Обнули какой-нибудь xmm7 (pxor или xorps) и копи в нем результат addpd xmm7,xmm0 3) в цикле суммирования addpd по любому тормозят, т.к. являются зависимыми и имеют латентность 3-5 тактов в зависимости от проца. Для ускорения нужно развернуть цикл еще на 2 и использовать независимые накопления в двух регистрах Код (Text): pxor xmm6,xmm6 pxor xmm7,xmm7 @@: movapd xmm0,[esi] mulpd xmm0,[esi] ;или movapd xmm1,[esi] + mulpd xmm0,xmm1 addpd xmm6,xmm0 movapd xmm0,[esi+16] mulpd xmm0,[esi+16] ;или movapd xmm1,[esi] + mulpd xmm0,xmm1 addpd xmm7,xmm0 add esi,32 sub ecx,1 jnz @B addpd xmm7,xmm6
Так ты по-человеески объясни, что за алгоритм, что он призван делать, какие задачи решать, какие ты сам попытк предпринимал, тогда и у людей, глядишь, появится желание тебе помочь. А то бросил шмот кода, нати, оптимизируйте.
Извините что не обяснил сразу! єто процедура определенья квадрата нормы вектора. 1) (LMass-2)^2 - длина вектора 2) fst qword ptr [edi]-сглупил
leo если не секрет? в чем выигрыш при разбитии цикла на 2? Код ниже выполница за первый проход movapd xmm0,[esi] mulpd xmm0,[esi] ;или movapd xmm1,[esi] + mulpd xmm0,xmm1 addpd xmm6,xmm0 а этот за следующий проход в цикле movapd xmm0,[esi+16] mulpd xmm0,[esi+16] ;или movapd xmm1,[esi] + mulpd xmm0,xmm1 addpd xmm7,xmm0 циклов станет меньше, а инструкций нет… в чем же выгода?
leo ты прав так действительно быстрее!спасибо!) но всеже почему? общее количество инструкций не меняеться?
AndreyATC В современных процессорах рулит спекулятивное исполнение циклов и ветвлений, т.е. если инструкции в теле цикла выполняются дольше, чем происходит доставка новых операций из кэша, то выполнение следующей итерации цикла начинается еще до завершения предыдущей. Поэтому если сложения зависимы, то следующий addpd должен ждать завершения предыдущего, а если независимы, то они могут частично перекрываться Вот для наглядности примерная диаграмма для P4 Код (Text): movapd dxxxxxx................. //d - dispatch по 3 мопа за такт movapd d.xxxxxx................ //x - eXecute, число тактов = latency mulpd d.......xxxxxx.......... <-- моп загрузки и при mulpd r,m и при (mov r,m + mulpd r,r) addpd .d............xxxx...... <-- add1 movapd .d.xxxxxx.........|..... movapd .d..xxxxxx........|..... mulpd ..d.......xxxxxx..|..... addpd ..d.............xxxx.... <-- add2 не зависит от add1, поэтому не ждет его add ..dx...............|.... завершения, что приводит к экономии 2 тактов на цикл sub ...dx..............|.... jnz ...dx..............|.... ---------------------------|---| movapd ....dxxxxxx............| <-- следующая итерация начинается не дожидаясь movapd ....d.xxxxxx...........| завершения предыдущей mulpd ....d.......xxxxxx.....| addpd .....d............xxxx.| <-- add1 зависит от предыдущего add1 movapd .....d.xxxxxx..........| movapd .....d..xxxxxx.........| mulpd ......d.......xxxxxx...| addpd ......d.............xxxx <-- add2 зависит от предыдущего add2, но не зависит от add1 add ......dx................ sub .......dx............... jnz .......dx............... -------------------------------- дальше все повторяется В итоге имеем 4 такта на цикл из двух сложений, а без разворота было бы 4 такта на одно сложение PS: Все равно я не понял, почему длина вектора = (LMass-2)^2 а не просто LMass ? И еще, раз уж речь идет об оптимизации, то деление на степень 2 нужно выполнять сдвигом, а не div-ом Код (Text): mov edx,eax shr eax,2 ;eax=eax/4 and edx,3 ;edx = остаток 0..3
leo спс все понял) давай я все же попытаюсь обяснить почему я написал прогу решенья систем линейных уравнений больших порядков методом итераций(Ланцоша)! Она заполняется по шаблону! т.е я не ввожу разреженую матрицу вручную! Я задаю шаблон(матрицу) скажем 100*100, а получаю систему 10000*10000 уравнений! LMass - єто размерность матрицы шаблона, а так как она для удобства обрамлена нулями то реальная размерность = размерность - 2 (ноля которыми она обрамлена) вот в принципе и все)