Время выполнения

  • Автор темы n00n00
  • Дата начала
N

n00n00

#1
Добрый день
Странная проблема-пытаюсь разобраться с алгоритмами обработки изображений,сейчас пишу гауссовское размытие
И вылазит очень большое время исполнения
вот этот код

Код:
for(int i = -KNN_WINDOW_RADIUS; i <= KNN_WINDOW_RADIUS; i++)
for(int j = -KNN_WINDOW_RADIUS; j <= KNN_WINDOW_RADIUS; j++)
{
weight=expf( - ((i * i + j * j) * INV_KNN_WINDOW_AREA) );
if((((ix+i)<rows)&((iy+j)<cols))&(((ix+i)>0)&((iy+j)>0)))
acc += (zxc[ix+i][iy+j]);
исполняется за 53 миллисекунды
стоит добавить в последнюю строку умножение
C++:
 acc += (zxc[ix+i][iy+j])*weight;
время исполнения становится 650 миллисекунд.
Несмотря на то что описанный кусок сам крутится пару тысяч раз,я подозреваю что время выполнения не должно так сильно возрастать.
Так и должно быть?
 
?

????

#2
1. смотри ассемблерный код, что генерирует компилятор, смотри как можно оптимизировать
2. включи оптимизацию при сборке проекта, проверь не улучшилось ли быстродействие
 
N

n00n00

#3
<!--shcode--><pre><code class='asm'> acc += (zxc[ix+i][iy+j]);
00411639 mov eax,dword ptr [ix]
0041163F add eax,dword ptr
00411645 mov ecx,dword ptr [iy]
0041164B add ecx,dword ptr [j]
00411651 mov edx,dword ptr [zxc]
00411654 mov eax,dword ptr [edx+eax*4]
00411657 fld dword ptr [eax+ecx*4]
0041165A fadd dword ptr [acc]
0041165D fstp dword ptr [acc]
acc*=weight;}
00411660 fld dword ptr [acc]
00411663 fmul dword ptr [weight]
00411666 fstp dword ptr [acc]
00411669 jmp wmain+1BCh (41157Ch
)[/CODE]
ассемблерный код выдает такой
как я думаю весь затык происходит в строчках выделенных жирным
но почему??
буду очень благодарен за подсказку
 

grigsoft

Well-known member
15.11.2005
735
0
#4
Так KNN_WINDOW_RADIUS - это сколько?

Добавлено: Может быть проблема в том что в первом случае вычисление weight выбрасывается, из-за того что оно не используется? Как минимум i*i можно наружу вывести.

Добавлено: И если KNN_WINDOW_RADIUS - константа, то все веса можно расчитать однократно в таблицу.
 
N

n00n00

#5
KNN_WINDOW_RADIUS - 3
и весь этот код тоже где то пару тысяч раз крутится
и я с ассемблером не знаком=(
 

grigsoft

Well-known member
15.11.2005
735
0
#6
Его знать и не нужно. Для начала стоит лишь посмотреть в асм для случая когда последнего умножения нет - верно ли предположение что тогда weight не вычисляется вообще? Если все же вычисляется, тогда надо еще думать где проблема. Если нет - тогда похоже все время в expf. Что она делает?

Добавлено: С ходу вычисление weight стоит под следующий if внести.
 
N

n00n00

#7
grigsoft
вы правы
в одном случае weight не вычисляется
значит expf тратит так много времени
expf это exp() float
 

grigsoft

Well-known member
15.11.2005
735
0
#8
Ну значит надо массив на KNN_WINDOW_RADIUS*KNN_WINDOW_RADIUS*4 элементов, и рассчитать туда weight на первом проходе. В дальнейшем использовать уже рассчитанное значение.
 
N

n00n00

#9
большое спасибо!
не понимаю как я сам до этого не додумался.
 
A

artishok

#10
ходила на мастер класс по параллельному программированию, но там так о нем ничего и не сказали) зато так много о том как сократить время выполнения прог, очень полезно оказалось послушать...после этого моя прога стала работать в 10 раз быстрее) главное использовать уже известные и хорошие алгоритмы, анализировать код и все будет гуд)