Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Tightly Coupled Memory
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Системы на ПЛИС - System on a Programmable Chip (SoPC)
sifadin
Есть программа размером под 2Мб, которая выполняется из SDRAM
Столкнулся с тем что вот такой кусок кода
col1=*videomem;

if ((col1 & 0xff000000)!=0) return 1;
if (1) {
if ((col1 & 0xff000000)==0)
offset1=X1;
offset1=offset1*1024;
offset1=offset1+Y1;
offset1=(offset1<<2);
}
выполняется 1,5 мкс при частоте 100МГц
Решил повысить быстродействие, введением Tightly Coupled Memory под инструкции
И сразу столкнулся с трудностью - как запихнуть нужную мне процедуру в эту память
При объявлении
void PP () __attribute__ ((section (".onchip_memory2_0_s2")));
компилятор выдает ошибку relocation truncated to fit
смысл ее мне не очень ясен но видимо линкер не может поместить ее в эту область потому что остальной код
в SDRAM
как быть? Весь код туда не влезет
vadimuzzz
а как у вас с кэшем инструкций? я так понимаю, это должна быть его работа. Tightly Coupled Memory обычно имеет смысл под обработчики прерываний использовать. да, а как меряли время выполнения?
sifadin
Цитата(vadimuzzz @ Jul 1 2011, 16:43) *
а как у вас с кэшем инструкций? я так понимаю, это должна быть его работа. Tightly Coupled Memory обычно имеет смысл под обработчики прерываний использовать. да, а как меряли время выполнения?

4 к кэша
измерял По осцилографу. Зациклил код и в конце поставил обращение к внешнему устройству (высокоскоросному).
По стробу записи смотрел частоту обращений
Пробовал закоментировать код разница впечатляет с кодом около 1МГц, без 20МГц (устройство дает такты ожидания)
Теоретически при таком раскладе он должен работать из кэша может сдвиговые операции съедают время
Какие опции компилятора надо включить чтобы он оптимизировал код по быстродействию?

Да дело было в оптимизации включил -O3 время уменьшилось на порядок
Не знал что это такая сильная штука
vadimuzzz
для того кода время дикое. при 4к кэша зацикливаемый кусок наверняка исполняется не с DRAM, Tightly Coupled Memory тут не поможет. посмотрите промежуточный ассемблер (в objdump). можно еще сигналтапом посмотреть. -O3 - это чревато, лучше -O2
id_gene
+1 смотрите листинг. Можно промоделировать, если ресуры позволяют.

Поковырял свои старые коды, вот такая строчка у меня есть (переложил одну функцию во флешку)
void my_init (void) __attribute__ ((section (".cfi_flash_2.txt")));

Почему с txt - не помню wacko.gif
При этом строчка это в файле заголовков (при декларации), а не при описании функции.

Как называются секции в вашем случае можно посмотреть в _syslib/Release/system_description/generated.x

Но лучше, конечно, разобраться, почему так медленно.
sifadin
с O3 время того куска составляет 100нс вроде это соответствует

А чем череват O3?

vadimuzzz
Цитата(sifadin @ Jul 8 2011, 17:46) *
А чем череват O3?

есть риск получить нестабильную программу. имеет смысл только в приложении к какому-то конкретному коду, иначе все эти разговоры - сравнение теплого с мягким. на одних задачах может дать падение производительности, на других - прирост, на третьих - вообще глюки. т.е. для конкретной программы можно поиграться с флагами (-O* это еще не все), поглядеть на результат. еще это зависит от версии компилятора. вот на пальцах: http://www.insidepro.com/kk/231/231r.shtml
sifadin
Цитата(vadimuzzz @ Jul 8 2011, 15:19) *
есть риск получить нестабильную программу. имеет смысл только в приложении к какому-то конкретному коду, иначе все эти разговоры - сравнение теплого с мягким. на одних задачах может дать падение производительности, на других - прирост, на третьих - вообще глюки. т.е. для конкретной программы можно поиграться с флагами (-O* это еще не все), поглядеть на результат. еще это зависит от версии компилятора. вот на пальцах: http://www.insidepro.com/kk/231/231r.shtml


Спасибо, посмотрю
WitFed
Я думаю, что сам исходник:
CODE
if ((col1 & 0xff000000)!=0) return 1;
if (1) {
if ((col1 & 0xff000000)==0)
offset1=X1;
offset1=offset1*1024;
offset1=offset1+Y1;
offset1=(offset1<<2);
}

должен выглядеть так:
CODE
if ((col1 & 0xff000000)!=0) return 1;
offset1=X1;
offset1=offset1*1024;
offset1=offset1+Y1;
offset1=(offset1<<2);

Это эквивалентно и гораздо яснее. Вторичная проверка не нужна, да и вдруг оптимизатор её сам не выбросит.
Там на самом деле из всего получается простая формула:
CODE
offset1 = (X1<<12) + (Y1<<2);

, которую можно вычислять однострочно. Даже завести временные переменные с (X1<<12) и (Y1<<2), обновляемые в тех местах, где исходные меняются.
Может быть, это еще что-то ускорит на десяток тактов. Можно посравнивать сдвиги с умножением -- оно бывает аппаратное и на LE, сдвиги тоже им. Barrel можно настроить.
Само помещение кода в другой тип памяти вряд ли даст выигрыш -- в кэше он всю жизнь сидит при постоянном исполнении, а кэш из того же теста, что и пресловутая Tightly Coupled, да на вызов куча тактов пойдет. Легче само это тело текущей функции сделать inline-функцией, чтобы return-ов было поменьше.
Ну и, конечно, главная оптимизация уходом от -О0 получается wink.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.