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

Тема в разделе "Общие вопросы по С и С++", создана пользователем n00n00, 10 июн 2010.

  1. n00n00

    n00n00 Гость

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

    Код (Text):
    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. включи оптимизацию при сборке проекта, проверь не улучшилось ли быстродействие
     
  3. n00n00

    n00n00 Гость

    <!--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]
    ассемблерный код выдает такой
    как я думаю весь затык происходит в строчках выделенных жирным
    но почему??
    буду очень благодарен за подсказку
     
  4. grigsoft

    grigsoft Well-Known Member

    Регистрация:
    15 ноя 2005
    Сообщения:
    735
    Симпатии:
    0
    Так KNN_WINDOW_RADIUS - это сколько?

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

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

    n00n00 Гость

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

    grigsoft Well-Known Member

    Регистрация:
    15 ноя 2005
    Сообщения:
    735
    Симпатии:
    0
    Его знать и не нужно. Для начала стоит лишь посмотреть в асм для случая когда последнего умножения нет - верно ли предположение что тогда weight не вычисляется вообще? Если все же вычисляется, тогда надо еще думать где проблема. Если нет - тогда похоже все время в expf. Что она делает?

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

    n00n00 Гость

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

    grigsoft Well-Known Member

    Регистрация:
    15 ноя 2005
    Сообщения:
    735
    Симпатии:
    0
    Ну значит надо массив на KNN_WINDOW_RADIUS*KNN_WINDOW_RADIUS*4 элементов, и рассчитать туда weight на первом проходе. В дальнейшем использовать уже рассчитанное значение.
     
  9. n00n00

    n00n00 Гость

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

    artishok Гость

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

Поделиться этой страницей