Сравнение быстродействия
Добавлено: 28 дек 2010, 08:38
Кто-нибудь сравнивал быстродействие FFT на С с аналогичной процедурой из Фортрановской библиотеки?
Теория и практика цифровой обработки сигналов
http://ru.dsplib.org/forum/
Нет, к сожалению Вы ОЧЕНЬ глубоко заблуждаетесь. Скорость в пределах плав. точки не зависит от разрядности -- по кр. мере до тех пор, пока используется компилятор Микрософт (т.е. система команд i387) -- вычисления с плав. точкой всегда делаются для 10-байтового представления, а далее по мере необходимости округляются для сохранения в переменных double (8 байтов) либо float (4 байта). При использовании SSE2 (GNU GCC для x64 по умолчанию) ситуациия, слегка отличаясь в деталях, в целом та же. С точки зрения времени доступа к памяти -- тоже ни выигрыша, ни проигрыша нет -- потому как процессор (точнее, контроллер памяти) за один раз считывает не менее Cache Line Size (обычно 8 или 16) 32-разрядных слов.3. Еще одним параметром влияющим на скорость является разрядность. Чем больше разрядность тем меньше скорость. Наличие плавающей точки значительно уменьшает скорость и сильно уменьшает точность
(для float вместо long - это 3 байта вместо 4-х = 256 раз и еще хуже для double вместо int_64). Однако на относительно медленных процессорах с очень быстрым арифметическим блоком наличие плавающей точки не критично.
Код: Выделить всё
/* make the one sample conversion
*/
static void MakeSample(LRCH *ch, const double *hpr)
{
double hilb;
int i, ix;
hilb = ch -> s_in * hpr[0]; // все переменные -- double
for(i = 1, ix = ch -> ixCur; i <= n_delay; ++i)
{
ix -= 2; // take PREVIOUS value (step 2)
if(ix < 0)
ix += k_M;
hilb += ch -> s_buf[ix] * hpr[i];
}
// ....................
// indexes
ch -> ixCur = (ch -> ixCur + 1) % k_M;
ch -> ixOutRe = (ch -> ixOutRe + 1) % k_M;
}
Код: Выделить всё
/* make the one sample conversion
*/
static void MakeSample(LRCH *ch, const HSI32 *hpr)
{
HSI32 hilb;
#if 0 // это все закомментировано до #else !!!!!!
int i, ix;
hilb = ch -> s_in * (long long)hpr[0];
for(i = 1, ix = ch -> ixCur; i <= n_delay; ++i)
{
ix -= 2; // take PREVIOUS value (step 2)
if(ix < 0)
ix += k_M;
hi += ch -> s_buf[ix] * (long long)hpr[i];
}
#else
hilb = mk_hilb(ch -> s_in, ch -> s_buf, hpr, ch -> ixCur);
#endif
// .....................
// indexes
ch -> ixCur = (ch -> ixCur + 1) % k_M;
ch -> ixOutRe = (ch -> ixOutRe + 1) % k_M;
}
/* make Hilbert's transform
*/
static HSI32 mk_hilb(HSI32 s_in, HSI32 *s_buf, const HSI32 *hpr,
int ixCur)
{
int cnt;
HSI32 k_M_bytes;
__asm
{
// умножение 32*32->64; сложения -- 64-битные; результат округляется до 32 бит
mov eax, k_M
shl eax, 2
mov k_M_bytes, eax
mov edi, hpr // hilb = s_in * hpr[0]
mov eax, s_in
imul DWORD PTR [edi]
mov ebx, eax // ecx:ebx -- accumulator
mov ecx, edx
mov eax, n_delay // counter
mov cnt, eax
mov esi, ixCur
shl esi, 2 // здесь была копирования shl esi, 255
add esi, s_buf // esi = &s_buf[ixCur]
hilb_loop:
sub esi, 2 * 4 // take previous value
add edi, 4
cmp esi, s_buf
jae SHORT s_buf_ptr_ok
add esi, k_M_bytes
s_buf_ptr_ok:
mov eax, [esi]
imul DWORD PTR [edi]
add ebx, eax
adc ecx, edx
dec cnt
jnz SHORT hilb_loop
mov eax, ecx // the result must be 32 bits
shld eax, ebx, 1 // s32 * s32 == s63, not i64!!
}
}