program Sum64; uses sysutils; {$APPTYPE CONSOLE} const N = 5000; Rep = 500000; type TDArray = Array[1..N] of Double; var DArray : TDArray; f: Double; procedure Sum1; {rdx - @DArray; rcx - N; xmm0 - sum(a), xmm1 - a, xmm3 - f} asm mov rax, Rep @rep: {Вычисление суммы} mov rcx, N pxor xmm0, xmm0 pxor xmm1, xmm1 pxor xmm3, xmm3 lea rdx, DArray movsd xmm3, [f] @next: movsd xmm1, [rdx+ rcx*8-8] comisd xmm1, xmm3 jbe @continue addsd xmm0, xmm1 @continue: sub rcx, 1 jnz @next {Вычисление суммы end} sub rax, 1 jnz @rep end; procedure Sum2; {rdx - @DArray; rcx - N; xmm0 - sum(a), xmm1 - a, xmm2 - copy a, xmm3 - f} asm mov rax, Rep @rep: {Вычисление суммы} mov rcx, N pxor xmm0, xmm0 pxor xmm1, xmm1 pxor xmm2, xmm2 pxor xmm3, xmm3 lea rdx, DArray movsd xmm3, [f] @next: movsd xmm1, [rdx+ rcx*8-8] movaps xmm2, xmm1 cmppd xmm1, xmm3,6 {Сравниваем с f?} pand xmm1, xmm2 {Обнуляем если меньше f} addpd xmm0, xmm1 sub rcx, 1 jnz @next {Вычисление суммы end} sub rax, 1 jnz @rep end; Procedure Sum3; {rdx - @DArray; rcx - N; xmm0 - sum(a), xmm1 - a, xmm2 - copy a, xmm3 - f} asm mov rax, Rep @Rep: {Вычисление суммы} lea rdx, DArray pxor xmm0, xmm0 pxor xmm1, xmm1 pxor xmm2, xmm2 mov rcx, N movddup xmm3, [f] {Переносим с дублироваием f} btr rcx, 0 {Кол-во элеменов массива нечётноё?} jnc @next {Нет - переходим на суммирование упакованных} movsd xmm1, [rdx+ rcx*8] {Да - загружаем нечетный элемент} movaps xmm2, xmm1 {Делаем копию для срвнения} cmpsd xmm1, xmm3,6 {Сравниваем с f?} pand xmm1, xmm2 {Обнуляем если меньше или равно f} addsd xmm0, xmm1 {Накапливаем сумму} jrcxz @res {Если больше элементов нет, то обходим цикл} @next: movaps xmm1, [rdx+ rcx*8-16] {Загружаем два очередных элемента} movaps xmm2, xmm1 {Делаем копию для срвнения} cmppd xmm1, xmm3,6 {Сравниваем с f?} pand xmm1, xmm2 {Обнуляем если меньше f} addpd xmm0, xmm1 sub rcx, 2 jnz @next @res: haddpd xmm0, xmm0 {Вычисление суммы end} sub rax, 1 jnz @Rep end; var i: integer; Time1, Time2, d1, d2, d3: TDateTime; t: text; begin f:= 0.5; randomize; for i:= 1 to N do DArray[i]:= random; Time1:= Time; Sum1; Time2:= Time; d1:= Time2-Time1; Time1:= Time; Sum2; Time2:= Time; d2:= Time2-Time1; Time1:= Time; Sum3; Time2:= Time; d3:= Time2-Time1; Assign(t, 'sumtst.txt'); {$I-} Append(t); if IOResult <> 0 then Rewrite(t); {$I+} Writeln(t, 'N= ', N, ' Rep=', Rep); if d3 > 0 then writeln(t, 'd2/d1=', d2/d1:6:3, ' d3/d1=', d3/d1:6:3, ' d3/d2=', d3/d2:6:3) else writeln(t, 'd1=', d1, ' d2=', d2,', ', ' d3=', d3); close(t); end.