реклама на сайте
подробности

 
 
> Лишние NOP в ассемблерном коде
Degun
сообщение Oct 23 2007, 11:54
Сообщение #1


Частый гость
**

Группа: Новичок
Сообщений: 84
Регистрация: 4-09-07
Из: Москва
Пользователь №: 30 277



Code Composer Studio v 3.3; Процессор DM642 на evalution board.
Имеется программка, написанная на C++. После анализа её ассемблерного кода выяснилось, что после многих команд (LDW, ADD, CMPLT, AND, LDHU и др.) компилятор вставляет команду NOP, что естественно замедляет функционирование программы. Для чего это? Можно ли отключить вставку операторов NOP в ассемблерный код?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
qxov
сообщение Feb 13 2008, 10:16
Сообщение #2


Частый гость
**

Группа: Свой
Сообщений: 86
Регистрация: 22-03-07
Из: Санкт-Петербург
Пользователь №: 26 406



Очень тяжелый вложенный цикл. Нужно рассмотреть возможность упрощения. Возможно, имеет смысл разбить его на несколько значительно более простых.
Go to the top of the page
 
+Quote Post
Degun
сообщение Feb 19 2008, 12:55
Сообщение #3


Частый гость
**

Группа: Новичок
Сообщений: 84
Регистрация: 4-09-07
Из: Москва
Пользователь №: 30 277



Цитата(qxov @ Feb 13 2008, 13:16) *
Очень тяжелый вложенный цикл. Нужно рассмотреть возможность упрощения. Возможно, имеет смысл разбить его на несколько значительно более простых.

Значительно упростил вложенный цикл за счёт чуть большего расхода памяти. В результате для изображения с разрешением 640*480 процедура стала выполняться за 55 мсек. Но всё равно как-то много. Чтобы ещё такого оптимизировать?
Код
#include <stdlib.h>
#include <limits.h>
#include <csl_dat.h>

//Максимальное кол-во областей в изображении
#define MAX_AREAS 2000

//Ограниченный массив структур описателей областей!!!
#pragma DATA_ALIGN(8);
static short AreasMode[MAX_AREAS+1];
#pragma DATA_ALIGN(8);
static short AreasNumber[MAX_AREAS+1];
#pragma DATA_ALIGN(8);
static short AreasPixel[MAX_AREAS+1];

//Буферы для кэширования строк изображения
#pragma DATA_ALIGN(8);
static unsigned char ImageBuf[2][IMG_WIDTH_MAX];
#pragma DATA_ALIGN(8);
static unsigned short AreasBuf[2][IMG_WIDTH_MAX];


int dsp_SplitImage2AreasFast(
    unsigned char ** restrict Image,
    int Height, int Width,
    unsigned char *  restrict ModeNumb4Pix,
    unsigned short ** restrict Areas)
{
    //Изображение последовательно просматривается по строкам
    //для отнесения каждого пиксела к определённой области
    //Вычисление площади, занимаемой каждой областью и модой
    register int iAreasCounter;    //Счётчик количества областей в изображении
    register int iAreasInfoCounter;//Счётчик количества областей в контейнере
    register int iPrevAreaNumbL;   //Номер области предыдущей левой точки
    register int iPrevModeNumbL;   //Номер моды предыдущей левой точки
    //Временные переменные
    register int i, y, x, iSrcIndex, iDstIndex, iTmp;
    register int iCurrAreaNumb, iCurrModeNumb, iAreasInfoCountSav;
    register Uint32 id_LoadTransfer, id_SaveTransfer;
    register unsigned char * restrict pImageNextBuf;
    register unsigned char * restrict pImageCurrBuf;
    register unsigned short * restrict pAreasCurrBuf;
    register unsigned short * restrict pAreasPrevBuf;

    //Проверка корректности входных параметров
    if ((Image==0)||(ModeNumb4Pix==0)||(Areas==0)||(Width<=0)||(Height<=0)||
        (Width>IMG_WIDTH_MAX)||(Height>IMG_HEIGHT_MAX)) return -1;

    //Установка указателя на следующую строку изображения
    pImageNextBuf=ImageBuf[0];
    //Загрузка первой строки изображения
    id_LoadTransfer=DAT_copy(Image[0], pImageNextBuf, Width);
    //Начальная инициализация идентификатора канала сохранения
    id_SaveTransfer=DAT_XFRID_WAITNONE;

    //Обнуление счётчиков кол-ва областей
    iAreasCounter=iAreasInfoCounter=0;
    //Установка кол-ва областей максимально возможное для первой строки
    iAreasInfoCountSav=INT_MAX;
    //Обнуление указателя на текущую строку
    pAreasCurrBuf=NULL;
    //Цикл по всем точкам изображения
    for (y=0; y<Height; y++)
    {
        //Сохранение указателя на текущую строку изображения
        pImageCurrBuf=pImageNextBuf;
        //Сохранение указателя на предыдущую строку результата
        pAreasPrevBuf=pAreasCurrBuf;
        //Указатель на следующую строку изображения
        pImageNextBuf=ImageBuf[(y+1)&1];
        //Указатель на текущую строку результата
        pAreasCurrBuf=AreasBuf[y&1];
        //Начальные значения номера области и моды для левой точки
        iPrevModeNumbL=iPrevAreaNumbL=-1;
        //Ожидание окончания загрузки текущей строки изображения
        DAT_wait(id_LoadTransfer);
        //Запуск загрузки следующей строки изображения
        id_LoadTransfer = DAT_copy(Image[y+1], pImageNextBuf, Width);
        //Обработка очередной строки изображения
        for (x=0; x<Width; x++)
        {
            //Номер моды текущей точки
            iCurrModeNumb=ModeNumb4Pix[pImageCurrBuf[x]];
            //В зависимости от того принадлежит ли точка той же моде,
            //что и её левая точка, установка номера области
            if (iCurrModeNumb==iPrevModeNumbL)
                iCurrAreaNumb=iPrevAreaNumbL;
            else
            {
                //Добавление новой области
//                if (iAreasInfoCount>=MAX_AREAS) return -1;
                iCurrAreaNumb=iAreasInfoCounter;
                AreasMode[iAreasInfoCounter]=iCurrModeNumb;
                AreasNumber[iAreasInfoCounter]=iAreasInfoCounter;
                AreasPixel[iAreasInfoCounter]=x;
                //Инкремент счётчиков областей
                iAreasCounter++; iAreasInfoCounter++;
                //Запоминание номера области и моды для левой точки
                iPrevAreaNumbL=iCurrAreaNumb;
                iPrevModeNumbL=iCurrModeNumb;
            }
            //Установка номера области текущей точки
            pAreasCurrBuf[x]=iCurrAreaNumb;
        }
        //Обработка всех областей в текущей строке для выявления их связей
        //с областями на предыдущей строке
        for (; iAreasInfoCountSav<iAreasInfoCounter; iAreasInfoCountSav++)
        {
            iSrcIndex=iAreasInfoCountSav;
            iCurrModeNumb=AreasMode[iAreasInfoCountSav];
            iTmp=AreasPixel[iAreasInfoCountSav];
            if (iTmp>0) iTmp--;
            if (iAreasInfoCountSav==(iAreasInfoCounter-1))
                iCurrAreaNumb=Width-1;
            else
                iCurrAreaNumb=AreasPixel[iAreasInfoCountSav+1];
            iCurrAreaNumb=pAreasPrevBuf[iCurrAreaNumb];
            //Цикл по всем граничащим на предыдущей строке областям
            for (i=pAreasPrevBuf[iTmp]; i<=iCurrAreaNumb; i++)
            {
                if (AreasMode[i]!=iCurrModeNumb) continue;
                //На предыдущей строке найдена область с совпадающей модой,
                //которая соседствует с исходной
                iDstIndex=i;
                while(AreasNumber[iDstIndex]!=iDstIndex) iDstIndex=AreasNumber[iDstIndex];
                if (iSrcIndex!=iDstIndex)
                {
                    //Объединение двух кластеров областей
                    if (iSrcIndex<iDstIndex)
                    {
                        //Сохранение номера
                        AreasNumber[iDstIndex]=iSrcIndex;
                    }
                    else
                    {
                        //Сохранение номера
                        AreasNumber[iSrcIndex]=iDstIndex;
                        //Для дальнейшего объединения берётся меньший индекс
                        iSrcIndex=iDstIndex;
                    }
                    //Декремент кол-ва областей
                    iAreasCounter--;
                }
            }
        }
        //Сохранение кол-ва областей
        iAreasInfoCountSav=iAreasInfoCounter;
        //Ожидание окончания сохранения результата
        DAT_wait(id_SaveTransfer);
        //Сохранение строки результата
        id_SaveTransfer=DAT_copy(pAreasCurrBuf, Areas[y], sizeof(short)*Width);
    }

    //Обновление ссылок на области
    for (iSrcIndex=0; iSrcIndex<iAreasInfoCounter; iSrcIndex++)
    {
        //Поиск индекса назначения
        iDstIndex=iSrcIndex;
        while(AreasNumber[iDstIndex]!=iDstIndex) iDstIndex=AreasNumber[iDstIndex];
        //Обновление номера области
        AreasNumber[iSrcIndex]=iDstIndex;
    }

    //Могут оставаться независимые области с индексами больше iAreasCount
    for (iDstIndex=-1, iSrcIndex=iAreasCounter; iSrcIndex<iAreasInfoCounter; iSrcIndex++)
    {
        //Если эта область уже переадресована - все нормально
        if (AreasNumber[iSrcIndex]!=iSrcIndex) continue;
        //Поиск индекса для переадресации
        for (iDstIndex++; iDstIndex<iAreasCounter; iDstIndex++)
            if (AreasNumber[iDstIndex]!=iDstIndex) break;
        //Сохранение указателя на моду
        AreasMode[iDstIndex]=AreasMode[iSrcIndex];
        //Установка ссылки данной области на переадресованную
        AreasNumber[iSrcIndex]=iDstIndex;
        //Замена всех ссылок на эту область!!!!!!!!
        for (i=iSrcIndex; i<iAreasInfoCounter; i++)
            if (AreasNumber[i]==iSrcIndex) AreasNumber[i]=iDstIndex;
    }

    //Установка указателя на текущую загружаемую строку
    pAreasCurrBuf=AreasBuf[0];
    //Загрузка первой строки номеров областей
    id_LoadTransfer=DAT_copy(Areas[0], pAreasCurrBuf, sizeof(short)*Width);
    //Начальная инициализация идентификатора канала сохранения
    id_SaveTransfer=DAT_XFRID_WAITNONE;
    //Обработка всех строк
    for (y=0; y<Height; y++)
    {
        //Сохранение указателя на предыдущую строку результата
        pAreasPrevBuf=pAreasCurrBuf;
        //Указатель на следующую строку результата
        pAreasCurrBuf=AreasBuf[(y+1)&1];
        //Ожидание окончания загрузки текущей строки изображения
        DAT_wait(id_LoadTransfer);
        //Запуск загрузки следующей строки изображения
        id_LoadTransfer=DAT_copy(Areas[y+1], pAreasCurrBuf, sizeof(short)*Width);
        //Переписывание индексов удалённых областей на переназначенные
        for (x=0; x<Width; x++) pAreasPrevBuf[x]=AreasNumber[pAreasPrevBuf[x]];
        //Ожидание окончания сохранения результата
        DAT_wait(id_SaveTransfer);
        //Сохранение строки результата
        id_SaveTransfer=DAT_copy(pAreasPrevBuf, Areas[y], sizeof(short)*Width);
    }
    //Ожидание окончания сохранения результата
    DAT_wait(id_SaveTransfer);

    return iAreasCounter;
}


Сообщение отредактировал Degun - Feb 19 2008, 13:04
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Degun   Лишние NOP в ассемблерном коде   Oct 23 2007, 11:54
- - fontp   Цитата(Degun @ Oct 23 2007, 15:54) Code C...   Oct 23 2007, 12:04
|- - Degun   Цитата(fontp @ Oct 23 2007, 16:04) Это не...   Oct 23 2007, 12:15
|- - fontp   Цитата(Degun @ Oct 23 2007, 16:15) А разв...   Oct 23 2007, 12:28
|- - Edmundo   Цитата(Degun @ Oct 23 2007, 16:15) Не сов...   Oct 24 2007, 12:36
|- - Degun   А вообще можете посоветовать: 1. каких правил или ...   Oct 24 2007, 19:24
|- - Degun   Что можно сделать или оптимизировать в функции ниж...   Oct 26 2007, 12:06
|- - fontp   Неприятный какой алгоритм, сплошные условные опера...   Oct 26 2007, 12:40
||- - Degun   Как известно у TI C6000-го семейства 8 конвейеров....   Oct 30 2007, 20:12
||- - Edmundo   Цитата(Degun @ Oct 30 2007, 23:12) Как из...   Oct 30 2007, 20:32
||- - Degun   Цитата(Edmundo @ Oct 30 2007, 23:32) Куча...   Oct 31 2007, 06:29
||- - fontp   Цитата(Degun @ Oct 31 2007, 09:29) Если ц...   Oct 31 2007, 08:42
||- - Degun   Цитата(fontp @ Oct 31 2007, 11:42) Ну, он...   Oct 31 2007, 19:50
||- - fontp   Цитата(Degun @ Oct 31 2007, 22:50) А есть...   Oct 31 2007, 20:20
||- - Degun   Цитата(fontp @ Oct 31 2007, 23:20) Короче...   Nov 7 2007, 19:59
||- - fontp   Цитата(Degun @ Nov 7 2007, 22:59) Что-то ...   Nov 8 2007, 07:33
||- - vadkudr   Цитата(Degun @ Nov 8 2007, 04:59) Что-то ...   Nov 20 2007, 13:33
||- - SIA   Цитата(Degun @ Nov 7 2007, 22:59) Что-то ...   Mar 17 2008, 17:09
|- - qxov   Цитата(Degun @ Oct 26 2007, 16:06) Что мо...   Nov 16 2007, 10:07
|- - Degun   Цитата(qxov @ Nov 16 2007, 13:07) Я хотел...   Nov 16 2007, 13:08
|- - qxov   Цитата(Degun @ Nov 16 2007, 16:08) Задача...   Nov 16 2007, 21:53
||- - Degun   Цитата(qxov @ Nov 17 2007, 00:53) Вот пло...   Nov 17 2007, 10:54
|- - qxov   Цитата(Degun @ Nov 16 2007, 16:08) Алгори...   Nov 18 2007, 13:15
|- - qxov   Как успехи? Вот, набросал на коленке кусочек. Може...   Nov 19 2007, 20:42
|- - Degun   Цитата(qxov @ Nov 17 2007, 00:53) Вот так...   Nov 20 2007, 17:38
- - mdmitry   Возможно оффтор! В MATLAB ImageProcessing Tool...   Nov 18 2007, 11:09
- - Degun   Уважаемый qxov я сделал вашу функцию calcModes с п...   Nov 22 2007, 14:13
|- - qxov   Цитата(Degun @ Nov 22 2007, 17:13) Уважае...   Nov 22 2007, 14:49
- - qxov   А можно ли считать, что за пределами кадра есть ра...   Nov 22 2007, 20:00
|- - Degun   Цитата(qxov @ Nov 22 2007, 23:00) А можно...   Nov 23 2007, 11:58
|- - qxov   Цитата(Degun @ Nov 23 2007, 14:58) Да впо...   Nov 23 2007, 12:50
|- - Degun   Цитата(qxov @ Nov 23 2007, 15:50) Точно 7...   Nov 25 2007, 17:44
|- - qxov   Цитата(Degun @ Nov 25 2007, 20:44) Точно ...   Nov 26 2007, 07:41
|- - Degun   Цитата(qxov @ Nov 26 2007, 10:41) Я в DSP...   Nov 26 2007, 12:19
- - qxov   Не знаю, на сколько этот вариант подходит: если m...   Nov 26 2007, 19:07
|- - Degun   Цитата(qxov @ Nov 26 2007, 22:07) Не знаю...   Nov 27 2007, 12:26
|- - qxov   Цитата(Degun @ Nov 27 2007, 15:26) Вообще...   Nov 28 2007, 06:07
|- - Degun   Цитата(qxov @ Nov 28 2007, 09:07) Начинат...   Dec 6 2007, 17:40
|- - qxov   Цитата(Degun @ Dec 6 2007, 20:40) Такие с...   Dec 7 2007, 06:20
|- - Degun   Вот такой у меня получился код для DSP. Но для изо...   Feb 1 2008, 12:43
- - Николай Z   Цитата(Degun @ Oct 23 2007, 14:54) Code C...   Dec 6 2007, 23:23
- - Degun   Следующий вариант выполняется на 1 мсек быстрее, ч...   Mar 17 2008, 13:29


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd June 2025 - 22:42
Рейтинг@Mail.ru


Страница сгенерированна за 0.01487 секунд с 7
ELECTRONIX ©2004-2016