Трюки с float: быстрое вычесление логарифмов. (комментарии)
Это сообщение сгенерировано автоматически.
Эксперимент 1: 58,533мс Эксперимент 2: 57,398мс Эксперимент 3: 348,635мс Эксперимент 4: 369,977мс Эксперимент 5: 150,350мс Эксперимент 6: 38,044мс
1 и 2 - fastLog2 из подсказки
3 и 4 - logf
5 - sqrtf
6 - sqrt на sse
1) очевидно такую функцию как sqrt данным алгоритмом "ускорить" не удасться (можно только чуть замедлить и получить менее точный результат). аналогично с остальными функциями, которые есть в sse
2) как вычислить на sse логарифм - ненаю, потому в эксперименте он не участвовал. если кому не сложно - нарисуйте плиз (точности достаточно такойже, которая и у fastLog2)
union ADVFLOAT { float x; struct { unsigned int mant : 23; /* Mantissa without leading one */ unsigned int exp : 8; /* Exponential part */ unsigned int sign : 1; /* Indicator of the negative number */ }; }; #define LOG2E 1.44269504088896340736f float fastLog2(float x ) { ADVFLOAT ax; ax.x = x; int exp = ax.exp - 127; ax.sign = 0; ax.exp = 127; return ( ax.x - 1.0f) * LOG2E + exp; } float fastSqrt( float x ) { ADVFLOAT ax; int exp; ax.x = x; exp = ax.exp - 127; ax.sign = 0; ax.exp = 127; return ( ax.x - 1.0f) * LOG2E + exp; } double GetTime( ) { LARGE_INTEGER c,f; QueryPerformanceCounter( &c); QueryPerformanceFrequency( &f); long long ipart = c.QuadPart / f.QuadPart; long long fpart = c.QuadPart % f.QuadPart; return ( double)ipart + ( double)fpart / ( double)f.QuadPart; } int _tmain( int argc, _TCHAR* argv[]) { setlocale( LC_ALL, "Russian"); double time; const size_t arrlen = 10000000; __declspec( align( 16)) float* src = new float[arrlen]; __declspec( align( 16)) float* dst = new float[arrlen]; for( size_t i = 0; i < arrlen; i++) src[i] = ( float)rand( ) / ( float)RAND_MAX + ( float)rand( ); for( size_t xxx = 0; xxx < 4; xxx++) { time = GetTime( ); for( size_t i = 0; i < arrlen; i++) dst[i] = fastLog2( src[i]); time = GetTime( ) - time; printf( "Эксперимент 1: %.3fмс\n", time * 1000.0); __declspec( align( 16)) float* _src = src; __declspec( align( 16)) float* _dst = dst; time = GetTime( ); for( size_t i = 0; i < arrlen; i++) *_dst++ = fastLog2( *_src++); time = GetTime( ) - time; printf( "Эксперимент 2: %.3fмс\n", time * 1000.0); time = GetTime( ); for( size_t i = 0; i < arrlen; i++) dst[i] = logf( src[i]); time = GetTime( ) - time; printf( "Эксперимент 3: %.3fмс\n", time * 1000.0); _src = src; _dst = dst; time = GetTime( ); for( size_t i = 0; i < arrlen; i++) *_dst++ = logf( *_src++); time = GetTime( ) - time; printf( "Эксперимент 4: %.3fмс\n", time * 1000.0); _src = src; _dst = dst; time = GetTime( ); for( size_t i = 0; i < arrlen; i++) *_dst++ = sqrtf( *_src++); time = GetTime( ) - time; printf( "Эксперимент 5: %.3fмс\n", time * 1000.0); __declspec( align( 16)) struct mms_rec { float r0, r1, r2, r3; }; size_t arrlen2 = arrlen / 4; mms_rec* _src2 = ( mms_rec*)src; mms_rec* _dst2 = ( mms_rec*)dst; time = GetTime( ); for( size_t i = 0; i < arrlen2; i++) _mm_store_ps( &( _dst2++)->r0, _mm_sqrt_ps( _mm_load1_ps( &( _src2++)->r0))); time = GetTime( ) - time; printf( "Эксперимент 6: %.3fмс\n", time * 1000.0); } return 0; }
вычисление
Heil Spellcheck!
JokerR
> вычисление
ыыы. мну не заметил. модеры тоже =))
грамотные формучане не переживут позора и все уйдут на дтф =))
JokerR
> Heil
а это слово что значит? спелчекер должен был его подчеркнуть полюбому!
JokerR
> вычисление
> Heil Spellcheck!
/facepalm.. сейчас поправлю :)))
Kloun
> а это слово что значит?
типа "my grammer is gooder" наврено :)
Обратные корни и деление ускорять не надо, они и так быстрые, еще на K6 было 3 такта при половинной точности.
Kloun
У тебя в коде тела функций fastLog2 и fastSqrt одинаковы :)
Hartmann
> У тебя в коде тела функций fastLog2 и fastSqrt одинаковы :)
посто хотел сделать еще sqrt, но чет потом бросил
зы.
все-таки интересно. ктонибудь на see логарифм нарисует?
JokerR
> Heil Spellcheck!
Тут Heil не из янки, а скорее из нацистко-германского. Типа Heil Hitler... хотя должно быть Hail Hitler...
> Kloun
Да пусть в 10 раз медленнее работает и вообще толку нету. Совет всё равно очень интересный...
Proteus
> Да пусть в 10 раз медленнее работает и вообще толку нету. Совет всё равно очень
> интересный...
интересный. ктоже спорит! а разобраться более досконально разве не иентересно?
Kloun
> все-таки интересно. ктонибудь на see логарифм нарисует?
http://gruntthepeon.free.fr/ssemath/
Стандартная функция C# System.Math.Log(double a) вычисляет 10000000 натуральных логарифмов в среднем за 610 мс. :) (на процессоре Turion X2).
hEil to the king babe?
Тема в архиве.