Перейти к содержанию
    

Blackfin BF561 & Visual DSP++ 5.0

Не могу придумать как измерять время выполнения отдельных функций при оптимизации проекта. Кто - чем пользуется? В VDSP вроде никаких спецсредств нет. Проекты у меня без VDK и ОС. Встроеных часов нет. CoreTimer почему-то выдаёт левые числа, в аномалиях об этом ни слова. Обычный таймер заведённый от slck - тоже как-то странно считает.

 

Поделитесь простенькой наработочкой плз. или мыслями.

 

Точность 1мс и хуже. Частота 500/100МГц.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не могу придумать как измерять время выполнения отдельных функций при оптимизации проекта. Кто - чем пользуется? В VDSP вроде никаких спецсредств нет. Проекты у меня без VDK и ОС. Встроеных часов нет. CoreTimer почему-то выдаёт левые числа, в аномалиях об этом ни слова. Обычный таймер заведённый от slck - тоже как-то странно считает.

 

Поделитесь простенькой наработочкой плз. или мыслями.

 

Точность 1мс и хуже. Частота 500/100МГц.

А что, разве нету у вашего процессора в ядре регистров Cycles/Cycles2, которые образуют 64-битный счетчик тактов. К ним можно обращаться и считывать значения тактов в любой момент времени. В VDSP, насколько помню, кое-какие средства для этого имеются (макросы, в доке описаны).

 

У BF53x такие регистры есть. У двухядерника тоже должно быть.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У BF53x такие регистры есть. У двухядерника тоже должно быть.
У 561-го тоже есть.

 

В VDSP, насколько помню, кое-какие средства для этого имеются (макросы, в доке описаны).

Если конкретизировать, то

START_CYCLE_COUNT
STOP_CYCLE_COUNT

- одиночное измерение и

CYCLES_INIT
CYCLES_START
CYCLES_STOP

- измерение со статистикой (максимальное, минимальное и среднее время исполнения).

 

Эти макросы описаны в <cycles.h> и определенны при наличии символа препроцессора DO_CYCLE_COUNTS

 

PS. Есть еще функция clock(), возвращающая значение этих регистров.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

PS. Есть еще функция clock(), возвращающая значение этих регистров.

 

Что интересно - функция clock(), тоже ведёт себя странно. При старте время прыгает вперёд на 4 секунды, и в середине программы иногда выдаёт левые значения.

Но остановился пока на нём, более менее адекватные значения даёт.

 

Использование cycles.h громоздко как-то.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Непонятно откуда левые значения. Достаточно написать

#include <sysreg.h>

static inline unsigned long sclock(void)

{

volatile unsigned long clk;

clk = sysreg_read(reg_CYCLES);

return clk;

}

 

Здесь использован только один регистр (на самом деле их два, но для замера быстродействия достаточно одгого), но это регистр аппаратный и он ниразу не глючит.

На старте программы регистр сбрасывается ресетом, потом прежде чем стать на брекпойнт в начале Вашей программы выполняется стартап - вот он и прыгнул. Если где ещё прыгает, так это от отладчика житаг

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что интересно - функция clock(), тоже ведёт себя странно.

 

Понял. Были проблемы с лонгами. Ниже рабочий код:

 

#include <services/services.h>
#include <time.h>
#include <stdio.h>

volatile time_t OldTime=0;
volatile u32 TimeDIV;

void PrintClock(char *Msg)
{
time_t T,D;
T=clock()>>10;
D=T-OldTime;
OldTime=T;

T=T/TimeDIV;
D=D/TimeDIV;
printf("Time = %8d ms %8d ms > %s \n",T,D,Msg);
}

void CheckClock(char *Msg)
{
u32 f_sclk,f_cclk,f_vco;
ADI_PWR_RESULT R1;

R1=adi_pwr_GetFreq(&f_cclk,&f_sclk,&f_vco);
printf("CoreA started %d F= %d MHz (%d & %d)\n",R1,f_cclk/1000000,f_sclk/1000000,f_vco/1000000); 
TimeDIV=((f_cclk>>10)/1000);
}

 

Вызываю так ( у меня проблемы с установкой частоты, поэтому всегда проверяю):

CheckClock();    
...
PrintClock("Start");
Test1();
PrintClock("Test 1");
...

 

Результат:

Device 0:a: CoreA started 0 F= 495 MHz (123 & 495)

Time = 0 ms 0 ms > Start

Time = 540 ms 540 ms > Test 1

Time = 540 ms 0 ms > Test 2

Time = 553 ms 12 ms > Test 3

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Непонятно откуда левые значения. Достаточно написать

#include <sysreg.h>

static inline unsigned long sclock(void)

{

volatile unsigned long clk;

clk = sysreg_read(reg_CYCLES);

return clk;

}

 

Здесь использован только один регистр (на самом деле их два, но для замера быстродействия достаточно одгого), но это регистр аппаратный и он ниразу не глючит.

Дык clock() делает тоже самое...

 

На старте программы регистр сбрасывается ресетом, потом прежде чем стать на брекпойнт в начале Вашей программы выполняется стартап - вот он и прыгнул. Если где ещё прыгает, так это от отладчика житаг
Стартап на 4 секунды? :07:

По-моему (но могу и ошибаться - проверить не на чем), jtag счетчик тактов останавливает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Дык clock() делает тоже самое...

 

Стартап на 4 секунды? :07:

По-моему (но могу и ошибаться - проверить не на чем), jtag счетчик тактов останавливает.

 

Нет. Я так понял, что была проблема в преобразованиях лонгов при делении на константу (1000). Сдвиг на 10 бит вправо решил проблему переполнения.

 

Программа у меня без брекпоинтов, но вывод printf не влияет на ход часов (не учитывается).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...