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

 
 
> Лишние 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
Ответов
fontp
сообщение Oct 23 2007, 12:04
Сообщение #2


Эксперт
*****

Группа: Свой
Сообщений: 1 467
Регистрация: 25-06-04
Пользователь №: 183



Цитата(Degun @ Oct 23 2007, 15:54) *
Code Composer Studio v 3.3; Процессор DM642 на evalution board.
Имеется программка, написанная на C++. После анализа её ассемблерного кода выяснилось, что после многих команд (LDW, ADD, CMPLT, AND, LDHU и др.) компилятор вставляет команду NOP, что естественно замедляет функционирование программы. Для чего это? Можно ли отключить вставку операторов NOP в ассемблерный код?


Это не ассемблерный код, а выход С-компилятора.

У TI такой подход, что программист (или компилятор) должен следить за длительностью выполнения инструкций (latency). Например, если умножение требует 5 тактов, то нужно пять тактов и ждать, в противном случае Вы выхватываете из конвейера неверный результат (что, однако, никто Вам запретить не может). Вот компилятор и борется с "открытым конвейером"

Есть единственный гарантированый способ избежать вставки NOP в ассемблерный код - написать самому на ассемблере, так чтобы без NOPов ;-) TMS серии 6х - это ведь кубик Рубика
Go to the top of the page
 
+Quote Post
Degun
сообщение Oct 23 2007, 12:15
Сообщение #3


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

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



Цитата(fontp @ Oct 23 2007, 16:04) *
Это не ассемблерный код, а выход С-компилятора.

А разве это не одно и тоже?
Цитата(fontp @ Oct 23 2007, 16:04) *
У TI такой подход, что программист (или компилятор) должен следить за длительностью выполнения инструкций (latency). Например, если умножение требует 5 тактов, то нужно пять тактов и ждать, в противном случае Вы выхватываете из конвейера неверный результат (что, однако, никто Вам запретить не может). Вот компилятор и борется с "открытым конвейером"
Есть единственный гарантированый способ избежать вставки NOP в ассемблерный код - написать самому на ассемблере, так чтобы без NOPов ;-) TMS серии 6х - это ведь кубик Рубика

Не совсем понятно. Если умножению, например, требуется 5 тактов, то соответствующая команда и будет выполняться необходимое кол-во тактов и только после после этого перейдёт к выполнению следующей. Или переход к выполнению следующей команды осуществляется сразу, а результат умножения будет готов только через 5 тактов?
Go to the top of the page
 
+Quote Post
Edmundo
сообщение Oct 24 2007, 12:36
Сообщение #4


Мастер
****

Группа: Свой
Сообщений: 730
Регистрация: 18-02-06
Из: Москва
Пользователь №: 14 474



Цитата(Degun @ Oct 23 2007, 16:15) *
Не совсем понятно. Если умножению, например, требуется 5 тактов, то соответствующая команда и будет выполняться необходимое кол-во тактов и только после после этого перейдёт к выполнению следующей. Или переход к выполнению следующей команды осуществляется сразу, а результат умножения будет готов только через 5 тактов?

Вы читали про ядро, про 8 "вычислителей", про кросс-пути и про параллельное выполнение?
И еще -- если поиграться оптимизацией -- можно получить неплохой код, не обязательно бросаться писать на АСМе. Ну да C vs. ASM -- это из другой оперы biggrin.gif


--------------------
شامل
Go to the top of the page
 
+Quote Post
Degun
сообщение Oct 24 2007, 19:24
Сообщение #5


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

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



А вообще можете посоветовать:
1. каких правил или приёмов необходимо придерживаться при написании C++ кода для DSP процессора (DM642), чтобы он имел максимальную производительность.
2. что лишнего можно выключить в DSP-BIOS, чтобы уменьшить вычислительную нагрузку на процессор.
Go to the top of the page
 
+Quote Post
Degun
сообщение Oct 26 2007, 12:06
Сообщение #6


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

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



Что можно сделать или оптимизировать в функции ниже в плане генерации оптимального кода для DSP-процессора?
Код
int SplitImage2Areas(unsigned char **Image, int **AreasNumb, int *Areas2Mode, int Width, int Height, int Thres1, int Thres2)
{
    if ((Image==0)||(Width<=0)||(Height<=0)||(AreasNumb==0)) return -1;

    int iPrevAreaNumbL=-1;  //Номер области предыдущей левой точки
    int iPrevModeNumbL=-1;  //Номер моды предыдущей левой точки
    int iPrevAreaNumbU=-1;  //Номер области предыдущей верхней точки
    int iPrevModeNumbU=-1;  //Номер моды предыдущей верхней точки
    int iPrevAreaNumbUL=-1; //Номер области предыдущей верхней левой точки
    int iPrevModeNumbUL=-1; //Номер моды предыдущей верхней левой точки
    int iPrevAreaNumbUR=-1; //Номер области предыдущей верхней правой точки
    int iPrevModeNumbUR=-1; //Номер моды предыдущей верхней правой точки
    int iAreasCount=0;      //Счётчик кол-ва областей
    int i, j, y, x, iNumb[4], iNumbCount, iDelta, iTmp;
    int iCurrPixel, iCurrAreaNumb, iCurrModeNumb;
    //Изображение последовательно просматривается по строкам
    //для отнесения каждого пиксела к определённой области
    for (y=0; y<Height; y++) for (x=0; x<Width; x++)
    {
        //Значение яркости текущего пикселя
        iCurrPixel=Image[y][x];
        //Номер области текущей точки
        iCurrAreaNumb=-1;
        //Номер моды текущей точки
        iCurrModeNumb=(iCurrPixel<Thres1?0:(iCurrPixel>Thres2?1:-1));
        //Определение параметров верхней правой точки
        if ((y>0)&&(x<(Width-1)))
        {
            iPrevAreaNumbUR=AreasNumb[y-1][x+1];
            iPrevModeNumbUR=Areas2Mode[iPrevAreaNumbUR];
        }
        //В зависимости от того является ли точка переходной
        if (iCurrModeNumb>=0)
        {
            //Эта точка не является переходной ни к одной из мод
            //Просмотр всех соседних уже размеченных ранее точек
            //для возможного определения номера области текущей точки
            if ((x>0)&&(iCurrModeNumb==iPrevModeNumbL)) {
                iCurrAreaNumb=iPrevAreaNumbL; //Левая точка
            }
            else if (y>0) { //Верхняя строка
                if (iCurrModeNumb==iPrevModeNumbU) {
                    iCurrAreaNumb=iPrevAreaNumbU; //Верхняя точка
                }
                else if ((x>0)&&(iCurrModeNumb==iPrevModeNumbUL)) {
                    iCurrAreaNumb=iPrevAreaNumbUL; //Верхняя левая точка
                }
                else if ((x<(Width-1))&&(iCurrModeNumb==iPrevModeNumbUR)) {
                    iCurrAreaNumb=iPrevAreaNumbUR; //Верхняя правая точка
                }
            }
        }
        else
        {
            //Текущая точка является переходной к любой области
            //Выбор наиболее близкой области
            iDelta=iTmp=-1;
            if (x>0) { //Левая точка
                iCurrAreaNumb=iPrevAreaNumbL;
                iDelta=abs(Image[y][x-1]-iCurrPixel);
            }
            if (y>0) { //Верхняя строка
                //Верхняя точка
                iTmp=abs(Image[y-1][x]-iCurrPixel);
                if ((iDelta<0)||(iDelta>iTmp)) {
                    iCurrAreaNumb=iPrevAreaNumbU;
                    iDelta=iTmp;
                }
                if (x>0) { //Верхняя левая точка
                    iTmp=abs(Image[y-1][x-1]-iCurrPixel);
                    if (iDelta>iTmp) {
                        iCurrAreaNumb=iPrevAreaNumbUL;
                        iDelta=iTmp;
                    }
                }
                if (x<(Width-1)) { //Верхняя правая точка
                    iTmp=abs(Image[y-1][x+1]-iCurrPixel);
                    if (iDelta>iTmp) {
                        iCurrAreaNumb=iPrevAreaNumbUR;
                        iDelta=iTmp;
                    }
                }
            }
            //Проверка на верхнюю левую точку всего изображения
            if (iCurrAreaNumb>=0)
                iCurrModeNumb=Areas2Mode[iCurrAreaNumb];
            else
                //Нужно добавить новую область с нулевой модой
                iCurrModeNumb=0;
        }
        //Если это новая область
        if (iCurrAreaNumb<0)
        {
            //Добавление нового объекта в коллекцию
            iCurrAreaNumb=iAreasCount++;
            Areas2Mode[iCurrAreaNumb]=iCurrModeNumb;
        }
        //Установка номера области текущей точки
        AreasNumb[y][x] = iCurrAreaNumb;
        //Сканирование окрестных точек для выяснения граничащих областей
        iNumbCount=0;
        if ((x==0)||(iPrevAreaNumbL!=iCurrAreaNumb))
        {
            //Просмотр левой точки
            if ((x>0)&&(iCurrModeNumb==iPrevModeNumbL)&&(iCurrAreaNumb!=iPrevAreaNumbL))
                iNumb[iNumbCount++]=iPrevAreaNumbL;
            //Просмотр верхней левой точки
            if ((y>0)&&(x>0)&&(iCurrModeNumb==iPrevModeNumbUL)&&(iCurrAreaNumb!=iPrevAreaNumbUL))
                iNumb[iNumbCount++]=iPrevAreaNumbUL;
            //Просмотр верхней точки
            if ((y>0)&&(iCurrModeNumb==iPrevModeNumbU)&&(iCurrAreaNumb!=iPrevAreaNumbU))
                iNumb[iNumbCount++]=iPrevAreaNumbU;
        }
        //Сканирование верхней правой точки (в любом случае независимо от iPrevAreaNumb!!!)
        if ((y>0)&&(x<(Width-1))&&(iCurrModeNumb==iPrevModeNumbUR)&&(iCurrAreaNumb!=iPrevAreaNumbUR))
            iNumb[iNumbCount++]=iPrevAreaNumbUR;
        //Добавление найденных граничных областей
        for (i=0; i<iNumbCount; i++)
        {
            iTmp=iNumb[i];
            bool bFind=false;
            for (j=0; j<i; j++) if (iNumb[j]==iTmp) {
                bFind=true;
                break;
            }
            if (!bFind) {
                //Здесь области добавляются к списку соседних областей
            }
        }
        //Запоминание номера области и моды для левой точки
        iPrevAreaNumbL=iCurrAreaNumb;
        iPrevModeNumbL=iCurrModeNumb;
        //Запоминание номера области и моды для верхней левой точки
        iPrevAreaNumbUL=iPrevAreaNumbU;
        iPrevModeNumbUL=iPrevModeNumbU;
        //Запоминание номера области и моды для верхней точки
        iPrevAreaNumbU=iPrevAreaNumbUR;
        iPrevModeNumbU=iPrevModeNumbUR;
    }

    return iAreasCount;
}


Сообщение отредактировал Degun - Oct 26 2007, 12:11
Go to the top of the page
 
+Quote Post
fontp
сообщение Oct 26 2007, 12:40
Сообщение #7


Эксперт
*****

Группа: Свой
Сообщений: 1 467
Регистрация: 25-06-04
Пользователь №: 183



Неприятный какой алгоритм, сплошные условные операторы, а процессор этого толком и не умеет.

Везде где возможно избавляйтесь от if заменяя их по-возможности на MAX и MIN. Т.е. определяя границы циклов вне циклов по возможности. Да и в циклах минимизируя количество условных операций. Условные операции - смерть конвейера

А вообще-то у TI есть руководство по оптимизации кода на C. Как проектировать конвейеры на С
Там много полезных советов
Go to the top of the page
 
+Quote Post
Degun
сообщение Oct 30 2007, 20:12
Сообщение #8


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

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



Как известно у TI C6000-го семейства 8 конвейеров. А вообще приведённый код функции будет выполняться на одном конвейере или на 8-ми. Т. е. будет ли компилятор загружать автоматически все конвейеры или только один и необходимо предпринимать специальные меры, чтобы загрузить остальные 7?
Go to the top of the page
 
+Quote Post
Edmundo
сообщение Oct 30 2007, 20:32
Сообщение #9


Мастер
****

Группа: Свой
Сообщений: 730
Регистрация: 18-02-06
Из: Москва
Пользователь №: 14 474



Цитата(Degun @ Oct 30 2007, 23:12) *
Как известно у TI C6000-го семейства 8 конвейеров. А вообще приведённый код функции будет выполняться на одном конвейере или на 8-ми. Т. е. будет ли компилятор загружать автоматически все конвейеры или только один и необходимо предпринимать специальные меры, чтобы загрузить остальные 7?

Куча ветвлений в виде if-ов -- не есть истинная обработка сигналов. А посему, не будет работа DSP воистину эффективна. Для этого можно и 8051 или ARM поставить. Не для этого рождены Обработчики Сигналов...


--------------------
شامل
Go to the top of the page
 
+Quote Post
Degun
сообщение Oct 31 2007, 06:29
Сообщение #10


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

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



Цитата(Edmundo @ Oct 30 2007, 23:32) *
Куча ветвлений в виде if-ов -- не есть истинная обработка сигналов. А посему, не будет работа DSP воистину эффективна. Для этого можно и 8051 или ARM поставить. Не для этого рождены Обработчики Сигналов...

Если цифровую обработку сводить только к линейной фильтрации и линейным алгоритмам вообще, то такую обработку вообще с лёгкостью можно и в ПЛИС запихнуть. Но настоящая интеллектуальность алгоритмов начинает проявляться при их нелинейности, что предполагает широкое использование if-ов. Поэтому на DSP-процессоры хотелось бы возложить именно такие более сложные алгоритмы. Да и та функция, которую я привёл не настолько сложна, чтобы сильно загружать процессор: она целочисленна; в ней нет никаких математических вычислений. Я бы даже сказал так: если уж он эту функцию не может выполнять быстро, то вообще что же он тогда может.
Go to the top of the page
 
+Quote Post
fontp
сообщение Oct 31 2007, 08:42
Сообщение #11


Эксперт
*****

Группа: Свой
Сообщений: 1 467
Регистрация: 25-06-04
Пользователь №: 183



Цитата(Degun @ Oct 31 2007, 09:29) *
Если цифровую обработку сводить только к линейной фильтрации и линейным алгоритмам вообще, то такую обработку вообще с лёгкостью можно и в ПЛИС запихнуть. Но настоящая интеллектуальность алгоритмов начинает проявляться при их нелинейности, что предполагает широкое использование if-ов. Поэтому на DSP-процессоры хотелось бы возложить именно такие более сложные алгоритмы. Да и та функция, которую я привёл не настолько сложна, чтобы сильно загружать процессор: она целочисленна; в ней нет никаких математических вычислений. Я бы даже сказал так: если уж он эту функцию не может выполнять быстро, то вообще что же он тогда может.



Ну, он там может всякую фильтрацию, всякие преобразоввания, интерполяцию, экстраполяцию.
Если алгоритм состоит из одних if-ов то вам нужен процессор без конвейера.
Кроме того сигнальный или мультимедийный алгоритм часто можно перепроектировать (не переписать) так, что if-ов не останется, или почти не останется. Например, у DSP для нахождения экстремумов есть специальные ассемблерные инструкции и на них надо выходить или программируя на ассемблере, или с помощью интринсиков. Есть и другие хитроумные специализированые инструкции о которых стандартный С ничего не знает. Но есть интринсики ассемблерные библиотечные функции? котрые их пользуют.

Все современные DSP имеют хороший длинный конвейер и алгоритмы для них должны состоять из коротких циклов с не более одного if внутри, чтобы выполняться эффективно. А в более старых DSP не было этой напасти, зато в них было так мало регистров, что всё приходилось программировать на ассемблере, на С ничего не писалось

Понятно, что это трудно объяснить своему менеджеру, который купил Вам самый дорогой процессор (10 млрд. МИПС :-)) на все случаи жизни. Менеджер - это ведь тот человек, который понятия не имеет, где он находится, но совершенно точно знает, кто виноват :-)

По поводу Вашего предыдущего вопроса - сам он ничего не будет загружать. Компилятор будет делать попытки, но ... оптимизирующий компилятор должен узнать один из известных ему шаблонов, чтобы сгенерировать эффективный код. C FIR фильтром он разберётся лучше программиста, а так не очень...
Что ему программист скажет загрузить (с помощью ассемблера или интринсиков) - то он примерно и загрузит
Go to the top of the page
 
+Quote Post
Degun
сообщение Oct 31 2007, 19:50
Сообщение #12


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

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



Цитата(fontp @ Oct 31 2007, 11:42) *
Ну, он там может всякую фильтрацию, всякие преобразоввания, интерполяцию, экстраполяцию.
Если алгоритм состоит из одних if-ов то вам нужен процессор без конвейера.

Конечно не из одних, но их достаточное кол-во. Типовые задачи цифровой обработки сигналов также присутствуют. Вообще с трудом представляю себе алгоритмы без if-ов. Например, сравнение одной переменной с другой и в зависимости от результата ветвление - это if. А уж без этого трудно представить большинство алгоритмов.
Цитата(fontp @ Oct 31 2007, 11:42) *
Понятно, что это трудно объяснить своему менеджеру, который купил Вам самый дорогой процессор (10 млрд. МИПС :-)) на все случаи жизни.

На самом деле производительность всего 4800 МИПС. Теоретически. Но чтобы их вытянуть у процессора на языке C\C++ нужно приложить массу усилий или перейти на ассемблер. Причём тип процессора был выбран вполне обосновано и претензий к этому у меня нет. Как показывает практика такой производительности процессора не хватает для обработки кадров с разрешением 768*576 с частотой 50 Гц по приведённому выше алгоритму, т. к. эта функция для указанного разрешения выполняется порядка 1 сек!
Цитата(fontp @ Oct 31 2007, 11:42) *
По поводу Вашего предыдущего вопроса - сам он ничего не будет загружать. Компилятор будет делать попытки, но ... оптимизирующий компилятор должен узнать один из известных ему шаблонов, чтобы сгенерировать эффективный код. C FIR фильтром он разберётся лучше программиста, а так не очень...
Что ему программист скажет загрузить (с помощью ассемблера или интринсиков) - то он примерно и загрузит

А есть ли документ где можно посмотреть типовые шаблоны алгоритмов?

Сообщение отредактировал Degun - Oct 31 2007, 19:52
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Degun   Лишние NOP в ассемблерном коде   Oct 23 2007, 11:54
|- - fontp   Цитата(Degun @ Oct 23 2007, 16:15) А разв...   Oct 23 2007, 12:28
||- - 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
- - qxov   Очень тяжелый вложенный цикл. Нужно рассмотреть во...   Feb 13 2008, 10:16
|- - Degun   Цитата(qxov @ Feb 13 2008, 13:16) Очень т...   Feb 19 2008, 12:55
- - Degun   Следующий вариант выполняется на 1 мсек быстрее, ч...   Mar 17 2008, 13:29


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

 


RSS Текстовая версия Сейчас: 20th June 2025 - 21:41
Рейтинг@Mail.ru


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