lamateur 0 5 декабря, 2008 Опубликовано 5 декабря, 2008 (изменено) · Жалоба Здравствуйте! Возникло сомнение, что правильно передаю данные через EDMA из внешней памяти (SDRAM) во внутреннюю (L2). А именно, на стартер ките на базе С6416 передача 16-ти КБайт занимает примерно 54000 тиков таймера, что соотвествует примерно 0.6 мсек реального времени (720 МГц) или скорости 25 МБайт/с. По-хорошему, скорость обмена между внешней и внутренней памятью должна быть раз в 20 больше! Передачу делаю Блок-синхронизированную из 2D в 1D: транслируется квадрат байтов размера 128 на 128. Замер времени производился на участке проверки соответствующего бита CIPR-регистра. Именно этот цикл проверки и занимает 54000 тиков. Прерывание я не отправляю, поскольку далее программа работает с переданными данными и необходимо знать, что передача окончена. вот пример участка кода, на котором производится замер: EDMA_setChannel(hEdma_fragm); while (1) { if (EDMA_intTest(FRAGM_EDMA_TCC)) { EDMA_intClear(FRAGM_EDMA_TCC); break; } Подскажите, пожалуйста, где искать ошибку. 1) Неправильно настроил канал передачи 2) Нельзя напрямую многократно опрашивать регистр CIPR 3) Существуют какие-то настройки памяти, которые надо изменить (например, через DSP/BIOS) 4) Неправильно произведен замер времени ... Изменено 5 декабря, 2008 пользователем lamateur Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bav 0 5 декабря, 2008 Опубликовано 5 декабря, 2008 · Жалоба думаю, п.4 попробуй поварьировать с разными размерами массива. запиши и пришли зависимость. попробуй тоже самое сделать через QDMA. и еще - на какой частоте тактируется SDRAM и какая толщина шины данных? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bve 1 5 декабря, 2008 Опубликовано 5 декабря, 2008 · Жалоба Попробуйте грамотно расположить массив во внешней памяти. Полная скорость SDRAM достигается, если данные берутся из одной строки, тогда скорость определяется тактовой частотой SDRAM. А вот если данные располагаются в другой строке, то тогда на активацию новой строки тратится 4-6 тактов SDRAM_CLK ( в зависимости от памяти ). Если у Вас идет частое обращение к разным строкам, то и получите малую скорость...... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rokhan 0 8 декабря, 2008 Опубликовано 8 декабря, 2008 · Жалоба 1) Скорее всего вы неправильно настроили. 2) Можно, EDMA_intTest(FRAGM_EDMA_TCC)) - макрос который опрашивает руками 3) настроки памяти всегда можно изменить - посмотрите при старте что то типа фукнцию init_dsp() в не производиться инициализая памяти, кеша и т.п. 4) Замер времени произведен скорее всего правильно - неправильно расмотрены результаты - к сведению - EDMA работает на частоте CPU/3. Скорее всего очень плохо настроен EDMA, но без конкретных цифиръ я сказать не могу. так что Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
lamateur 0 9 декабря, 2008 Опубликовано 9 декабря, 2008 · Жалоба bav, 1) для других размеров массивов объем переданных в секунду данных не меняется: 256х256 (64 КБайт) ~ 215000 тиков. 128х128 (16 КБайт) ~ 54000 тиков. 128х128 (1 КБайт) = 3407 тиков. 8х8 (64 Байт) = 245 тиков. Получается все те же 26МБайт/сек... если я правильно понял, что Вы имели ввиду. Кстати, внутренняя передача (из одной области L2 в другую) 4КБайт занимает 11000 тиков, что соответствует 33Мбайт/сек. 2) При передачи через QDMA скорости те же самые. Делал QDMA по примеру в spra636a.pdf (EDMA: Example Application), пример Subframe Extraction (стр. 49). Кстати как раз описан мой случай - экстракции малой прямоугольной области из большей области... 3) Память представляет из себя две спаренные 32-битные SDARM по 8 МБайт. Таким образом, общая полоса на 64 бит. Тактируется, если я правильно разобрался, с частотой ECLKOUT1, которая соответствует входной частоте EMIF: ECLKIN, а уже последняя в свою очередь либо внешняя, либо CPU/4, либо CPU/6. А вот где это задается - хоть убей - не нашел. Нашел только в комментах GEL-файла, что EMIF работает на 120MHz, наверное это и есть та самая ECLKIN. bve, Если я Вас правильно понял и правильно понял структуру памяти, в одном банке (на 16 Mbit) моей памяти: 2048 строк и 256 колонок. А массив байт 128х128 я беру из области 1024х1024, т.е. как минимум каждая новая последовательность в 128 байт будет экстрагироваться из новой строки памяти. Наглядно это показано в примере Subframe Extraction (см. выше). rokhan, на 3) Можете пояснить, где именно должна располагаться функция типа ini_dsp() или что именно она меняет: регистры EMIF, ядра,..? на 4) А что определяет частота работы EDMA? Могу предположить только, что частота самой передачи будет определяться "самым слабым" звеном в системе. В данном случае наименьшая частота - частота обращения к памяти через EMIF - 120MHz. Какие цифры позволили бы вам судить о правильной настройке EDMA? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rokhan 0 9 декабря, 2008 Опубликовано 9 декабря, 2008 · Жалоба 1. Если вы использовали стандартный DSP/BIOS проект то параметр что нибудь в роде... bios.GBL.USERINITFXN = prog.extern("c6416_init"); 2. Просто приведите пример кода которым вы инициализируете EDMA Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bav 0 9 декабря, 2008 Опубликовано 9 декабря, 2008 · Жалоба 3) Память представляет из себя две спаренные 32-битные SDARM по 8 МБайт. Таким образом, общая полоса на 64 бит. Тактируется, если я правильно разобрался, с частотой ECLKOUT1, которая соответствует входной частоте EMIF: ECLKIN, а уже последняя в свою очередь либо внешняя, либо CPU/4, либо CPU/6. А вот где это задается - хоть убей - не нашел. Нашел только в комментах GEL-файла, что EMIF работает на 120MHz, наверное это и есть та самая ECLKIN. убивать не будем :) задается регистрами: ECLKIN_SEL (DEVCFG.[17,16] and DEVCFG.[15,14]) проверь осцильником, какая там частота. еще есть подозрения, что EMIF сконфигурирован на работу с 8-ми битной памятью. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
lamateur 0 9 декабря, 2008 Опубликовано 9 декабря, 2008 · Жалоба задается регистрами: ECLKIN_SEL (DEVCFG.[17,16] and DEVCFG.[15,14]) проверь осцильником, какая там частота. еще есть подозрения, что EMIF сконфигурирован на работу с 8-ми битной памятью. А разве на C64xx есть Device Configuration Register? Я не смог найти. Пишут, что он только на 6713 присутствует. EMIF сконфигурирована на 64-битную SDRAM (регистр CECTL0: 0xffffffd3) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bav 0 9 декабря, 2008 Опубликовано 9 декабря, 2008 · Жалоба не знаю, может быть. посмотри таблицу Device Configuration Pins (BEA[20:13, 9:7], HD5, and BEA11) в документе SPRS146 вообще, не уверен в правильности подсчета числа тактов. попробуй вывести сигнал на GPIO и с помощью осцильника посмотри время копирования. чтобы результат получился точнее, сделай перекачку 100-1000 блоков (можно одних и техже и в тоже место, только убери оптимизацию компилятора) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
lamateur 0 10 декабря, 2008 Опубликовано 10 декабря, 2008 · Жалоба rokhan, Да, стандартный dsp/bios проект для dsk6416. В генерируемом cmd-файле есть такая строка: GBL_USERINITFXN = _FXN_F_nop; Извините, но пока не хватает опыта, чтоб делать какие-то выводы из этого. Вот листинг конфигурации и передачи с замером времени. Если что-то не очевидно, я поясню. #define FRAGM_EDMA_TCC 11 EDMA_Config cfgEdmaFragm = { EDMA_OPT_RMK( EDMA_OPT_PRI_LOW, EDMA_OPT_ESIZE_8BIT, EDMA_OPT_2DS_YES, EDMA_OPT_SUM_INC, EDMA_OPT_2DD_NO, EDMA_OPT_DUM_INC, EDMA_OPT_TCINT_YES, EDMA_OPT_TCC_OF(FRAGM_EDMA_TCC), EDMA_OPT_TCCM_OF(0), EDMA_OPT_ATCINT_NO, EDMA_OPT_ATCC_OF(0), EDMA_OPT_PDTS_DISABLE, EDMA_OPT_PDTD_DISABLE, EDMA_OPT_LINK_YES, EDMA_OPT_FS_YES ), EDMA_SRC_OF(NULL), EDMA_CNT_RMK(NULL,NULL), EDMA_DST_OF(NULL), EDMA_IDX_RMK(NULL,NULL), EDMA_RLD_RMK(0x0000,0x07E0) }; Frame =(Uint8 *)(0x80500000); hEdma_fragm = EDMA_open(EDMA_CHA_ANY,EDMA_OPEN_RESET); //пробовал так же ставить конкретный канал cfgEdmaFragm.cnt=(Uint32)((strbsize+2*delta-1)<<16) + (strbsize+2*delta); cfgEdmaFragm.idx=(Uint32)((FRAME_WIDTH-strbsize-2*delta)<<16); cfgEdmaFragm.src=(Uint32)(Frame+(32-delta)*FRAME_WIDTH +(32-delta)); cfgEdmaFragm.dst=(Uint32)(Fragm); EDMA_config(hEdma_fragm,&cfgEdmaFragm); TIMER_start(hTimer1); EDMA_setChannel(hEdma_fragm); while (1) { if (EDMA_intTest(FRAGM_EDMA_TCC)) { EDMA_intClear(FRAGM_EDMA_TCC); break; } } *tickcount1 = TIMER_getCount(hTimer1); Кстати, я изначально в теме не правильно оценил скорость передачи... 54000 тиков - это 52 МБайт/сек. Что тоже медленно. bav, Спасибо за ссылку на пдф. Да, действительно, конфигурационный пин BEA[17:16] отвечает за настройку частоты. Если я правильно понял, BEA - это имя, а номера этих пинов B18 и A18. Можете подсказать, как теперь через CCStudio узнать, какой сигнал на них подается и как подать свой? Физически - это ножки процессора, да? Осцильник я, конечно, рано или поздно возьму... ) Но я оценивал реалистичность измеряемых тиков обычным секундомером, запустив программу на 15 секунд реального времени. Соответствует. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bav 0 10 декабря, 2008 Опубликовано 10 декабря, 2008 · Жалоба как узнать через CCS не знаю. не приходилось. это можно узанть по схеме или положению джамперов. через ножки конфигурируется только во время сброса. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
lamateur 0 10 декабря, 2008 Опубликовано 10 декабря, 2008 · Жалоба bav, я на всякий случай еще раз акцентирую внимание на том факте, что передача в пределах внутренней памяти L2 тоже очень медленная: 76 Мбайт/сек. Может режим\частота и т.п. внешнего интерфейса тут ни при чем тогда и надо скорее внутреннюю память настраивать? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bav 0 10 декабря, 2008 Опубликовано 10 декабря, 2008 · Жалоба в общем, как писал выше, подозрение в не корректности подсчета тактов. другое дело, может, DMA долго инициализируется на передачу. попробуй обычное копирование с оптимизацией. скажу, что таких проблем не было. правда, DMA у меня гонял потоки по видеопортам. проводил эксперименты по работе кэша и по копированию данных во внудреннюю память с помощью QDMA, там скорости были значительно выше, чем у Вас. вот, откопал текст для таймера Timer.h #include "csl_timer.h" #define CPU_FREQUENCY 720000000 #define CLOCK_SCALE 8 // не понятно, делитель стоит на 8, т. е. должен быть делитель на 8 class Timer { TIMER_Handle handle; // int overhead; int strt; int stp; int clocks; public: Timer(); ~Timer(); int count(); void start(); void stop(); int ms(); int us(); int tic(); }; Timer.cpp #include "timer.h" Timer::Timer() { handle = TIMER_open(TIMER_DEVANY, TIMER_OPEN_RESET); TIMER_configArgs(handle, 0x000002C0, 0xFFFFFFFF, 0x00000000); //калибровка //вычисление времени срабатывания // int start_ = count(); /* called twice to avoid L1D miss.*/ // start_ = count(); // int stop_ = count(); // overhead = stop_ - start_; } //---------------------------------------- Timer::~Timer() { TIMER_close(handle); } //---------------------------------------- int Timer::count() { return TIMER_getCount(handle); } //---------------------------------------- void Timer::start() { strt = TIMER_getCount(handle); } //---------------------------------------- void Timer::stop() { stp = TIMER_getCount(handle); clocks = stp - strt;// - overhead; } //---------------------------------------- int Timer::tic() { return clocks * CLOCK_SCALE; } //---------------------------------------- int Timer::ms() { return (long)(clocks / (CPU_FREQUENCY / 1000 / CLOCK_SCALE) ); } //---------------------------------------- int Timer::us() { return (long)(clocks / (CPU_FREQUENCY / 1000000 / CLOCK_SCALE) ); } //---------------------------------------- сейчас поищу другие тексты вот, как делал копирование: ....... #include <csl_dat.h> ....... DAT_open (DAT_CHAANY, DAT_PRI_HIGH, DAT_OPEN_2D); unsigned short * src_ = src.Data();//x, y); unsigned short * src__ = &src_[x - offset_block + (y - offset_block)*width]; Uint32 copy_ID1 = DAT_copy2d ( DAT_2D1D, (void*)src__, (void*)in_buf, width_o_block*sizeof(unsigned short), height_o_block, width*sizeof(unsigned short) ); DAT_wait(copy_ID1); ............. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rokhan 0 10 декабря, 2008 Опубликовано 10 декабря, 2008 (изменено) · Жалоба 1. Почитай http://focus.ti.com/lit/an/spraa02/spraa02.pdf Тут всё вполне написано. рекомендации измени EDMA_OPT_PRI_LOW на EDMA_OPT_PRI_HIGH EDMA_OPT_ESIZE_8BIT на EDMA_OPT_ESIZE_32BIT тогда передача в твоём случает будет вестись словами в 64 бита. что увеличит скорость в 8 раз :) Это с ходу что можно сказать. Забыл предупредить для работы с 64 битами нужно иметь выравненые указатели на 64бита:) Изменено 10 декабря, 2008 пользователем rokhan Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
lamateur 0 10 декабря, 2008 Опубликовано 10 декабря, 2008 · Жалоба rokhan, Крутой документ этот spraa02! Буду разжевывать! Спасибо! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться