В значительной степени каждый раз, когда компилятор видит код с плавающей точкой, рукописная версия будет более быстрой. Основная причина - то, что компилятор не может выполнить устойчивые оптимизации. См. эту статью от MSDN для обсуждения предмета. Вот пример, где версия блока является дважды скоростью как версией C (скомпилированный с VS2K5):
#include "stdafx.h"
#include
float KahanSum
(
const float *data,
int n
)
{
float
sum = 0.0f,
C = 0.0f,
Y,
T;
for (int i = 0 ; i < n ; ++i)
{
Y = *data++ - C;
T = sum + Y;
C = T - sum - Y;
sum = T;
}
return sum;
}
float AsmSum
(
const float *data,
int n
)
{
float
result = 0.0f;
_asm
{
mov esi,data
mov ecx,n
fldz
fldz
l1:
fsubr [esi]
add esi,4
fld st(0)
fadd st(0),st(2)
fld st(0)
fsub st(0),st(3)
fsub st(0),st(2)
fstp st(2)
fstp st(2)
loop l1
fstp result
fstp result
}
return result;
}
int main (int, char **)
{
int
count = 1000000;
float
*source = new float [count];
for (int i = 0 ; i < count ; ++i)
{
source [i] = static_cast (rand ()) / static_cast (RAND_MAX);
}
LARGE_INTEGER
start,
mid,
end;
float
sum1 = 0.0f,
sum2 = 0.0f;
QueryPerformanceCounter (&start);
sum1 = KahanSum (source, count);
QueryPerformanceCounter (&mid);
sum2 = AsmSum (source, count);
QueryPerformanceCounter (&end);
cout << " C code: " << sum1 << " in " << (mid.QuadPart - start.QuadPart) << endl;
cout << "asm code: " << sum2 << " in " << (end.QuadPart - mid.QuadPart) << endl;
return 0;
}
И некоторые числа от моего ПК, выполняющего сборку конечных версий по умолчанию * глоток>:
C code: 500137 in 103884668
asm code: 500137 in 52129147
Из интереса, я подкачал цикл с dec/jnz, и это не имело никакого значения к синхронизациям - иногда более быстрый, иногда медленнее. Я предполагаю, что память ограничила карликов аспекта другие оптимизации.
Возгласы, я выполнял немного отличающуюся версию кода, и он произвел числа наоборот (т.е. C был быстрее!). Зафиксированный и обновленный результаты.
Разъяснить уже отправленное решение из-за вопросов в комментариях
import numpy
array = numpy.array([49, 51, 53, 56])
array = array - 13
произведет:
массив ([36, 38, 40, 43])