Скорость работы кода обычного приложения и приложения VDK Печать
Добавил(а) microsin   

При проектировании приложений, где процессор сильно загружен вычислениями (например, цифровая обработка сигналов), встает вопрос оценки быстродействия кода, когда он работает в разных условиях - обычное приложение, приложение VDK. Также важно с точки зрения выбора компромисса в распределении памяти узнать, насколько изменится скорость вычислений при выборе памяти для кода L1 или L3, или при выборе памяти для данных L1 или L3. В этой статье приведена информация по тестированию скорости работы кода в различных условиях.

[Как тестировалась скорость выполнения кода]

Скорость работы кода оценивалась комбинированным тестом, выполняющимся на процессоре Blackfin ADSP-BF538, частота ядра (CCLK) 327.68 МГц, частота шины 32.768 МГц. В начале тестируемого блока кода ножка порта устанавливалась в лог. 0 (зажигался светодиод), и в конце тестируемого кода ножка порта устанавливалась в лог. 1 (светодиод гас). Длительность интервала времени между этими двумя моментами измерялась с помощью осциллографа - чем интервал меньше, тем код работает быстрее. Один цикл теста выглядел следующим образом:

LED(1);                    //Зажечь светодиод: начало теста
fill_mem_rand_values();    //Заполнить память псевдослучайными значениями (запись в память)
check_mem_rand_values();   //Проверить псевдослучайную последовательность в памяти (чтение памяти)
LED(0);                    //Погасить светодиод: конец теста

Этот код был проверен в разных условиях: с включенной и выключенной оптимизацией, с размещением кода в памяти L1 и L3, с размещением тестируемого блока данных в памяти в L1 и L3, в условиях работы кода в обычном (не VDK) приложении и в условиях низкоприоритетного потока приложения VDK. Код, генерирующий псевдослучайную последовательность, был взят из кода FreeBSD (см. [1]), и его работа тестировалась как из памяти L1, так и из памяти L3. 

Результаты тестирования можно увидеть в таблицах ниже.

Таблица 1. Скорость работы кода в приложении VDK.

Условия проведения теста Код Данные Время, мс Загрузка, %(2)
Debug (ADC, UART, KBD, BAT, SCREEN)(1) sdram0 sdram0 167.8 100
Debug (ADC, UART, KBD, BAT) sdram0 sdram0 167.8 100
Debug (ADC, UART, KBD) sdram0 sdram0 167.6 99.88
Debug (ADC, UART) sdram0 sdram0 164 97.74
Debug (ADC) sdram0 sdram0 162.4 96.78
Release (ADC, UART, KBD, BAT, SCREEN) sdram0 sdram0 121.4 72.35
Debug (ADC, UART, KBD, BAT, SCREEN) L1_code sdram0 33.56 20.00
Debug (ADC, UART, KBD, BAT) L1_code sdram0 33.56 20.00
Debug (ADC, UART, KBD) L1_code sdram0 33.52 19.98
Debug (ADC, UART) L1_code sdram0 32.8 19.55
Debug (ADC) L1_code sdram0 17.1 10.19
Release (ADC, UART, KBD, BAT, SCREEN) L1_code sdram0 10.2 6.08
Debug (ADC, UART, KBD, BAT, SCREEN) sdram0 L1_data 152.55 90.91
Debug (ADC, UART, KBD, BAT) sdram0 L1_data 152.55 90.91
Debug (ADC, UART, KBD) sdram0 L1_data 152.36 90.80
Debug (ADC, UART) sdram0 L1_data 149.09 88.85
Debug (ADC) sdram0 L1_data 147.64 87.98
Release (ADC, UART, KBD, BAT, SCREEN) sdram0 L1_data 110.36 65.77
Debug (ADC, UART, KBD, BAT, SCREEN) L1_code L1_data 30.51 18.18
Debug (ADC, UART, KBD, BAT) L1_code L1_data 30.51 18.18
Debug (ADC, UART, KBD) L1_code L1_data 30.47 18.16
Debug (ADC, UART) L1_code L1_data 29.82 17.77
Debug (ADC) L1_code L1_data 15.55 9.26
Release (ADC, UART, KBD, BAT, SCREEN) L1_code L1_data 9.27 5.53

Примечания к таблице 1:

(1) Аббревиатурами ADC, UART, KBD, BAT и SCREEN показано, какие потоки работали в этом варианте измерения скорости кода (поток АЦП, последовательного порта консоли, опроса напряжения батареи и обновления экрана соответственно).
(2) В этом столбце показано относительное сравнение различных результатов тестирования, за 100% взят самый худший случай (1 строка таблицы, когда и код, и данные находятся в SDRAM), когда код выполняется медленнее всего.

Таблица 2. Скорость работы кода в обычном приложении (не VDK).

Условия проведения теста Код Данные Время, мс Загрузка, %(1)
Debug sdram0 sdram0 154.60 92.13
Release sdram0 sdram0 118.00 70.32
Debug L1_code sdram0 15.90 9.48
Release L1_code sdram0 9.63 5.74
Debug sdram0 L1_data 140.55 83.76
Release sdram0 L1_data 107.27 63.93
Debug L1_code L1_data 14.45 8.61
Release L1_code L1_data 8.75 5.22

Примечания к таблице 1:

(1) В этом столбце показано относительное сравнение различных результатов тестирования, за 100% взят самый худший случай из таблицы 1 (1 строка таблицы, когда и код, и данные находятся в SDRAM), когда код выполняется медленнее всего.

Оба приложения работали на процессоре ADSP-BF538 с тактовой частотой ядра 327.28 МГц (CCLK) и частотой шины 32.768 МГц (SCLK). К процессору была подключена внешняя память SDRAM на 32 мегабайта.

В приложении VDK работала система чтения АЦП (через SPORT, с помощью DMA с двойной буферизацией), поток анализа нажатий клавиатуры, поток обновления экрана ЖКИ (через SPI, также с использованием DMA), поток обработки порта UART (управляющая консоль), поток чтения батареи BAT (передача через SPI с использованием прерываний). Работа с аппаратурой производилась с помощью системы драйверов ADI (библиотека SSL).

В обычном приложении код выполнялся в главном цикле main, и поверх него работал только обработчик прерывания таймера, в котором был вставлен код опроса клавиатуры. 

[Выводы]

1. Код выполняется в 5 раз быстрее, если он размещен в памяти L1 (код находится в секции L1_code), по сравнению с памятью L3 (код находится в секции sdram0).

2. Код выполняется примерно в 1.1 раза быстрее, если он обрабатывает данные, размещенные в памяти L1 (данные находятся в секции L1_data), по сравнению с данными, находящимися в L3 (данные находятся в секции sdram0). Т. е. для обычной обработки, где обращение к памяти занимают незначительную часть времени, тип памяти не имеет большого значения. Но для для операций, где обращение к памяти занимает большую часть (например, для работы функции memcpy), выигрыш от использования памяти L1 может быть пятикратный.

3. Код обычного приложения выполняется примерно в 1.1..1.2 раза быстрее, чем код, который выполняется в низкоприоритетном потоке приложения VDK. Таким образом, использование VDK незначительно снижает скорость выполнения кода.

4. Включение оптимизации ускоряет работу кода примерно в 1.5 раза, независимо от прочих условий.

[Ссылки]

1rand.c: исходный код генератора псевдослучайных чисел.