Я пытаюсь измерить задержку чтения / записи между процессором ARM и FPGA на одной плате. Мне интересно, достаточно ли использовать глобальный таймер, чтобы сообщить об этой задержке в виде тактовых циклов, потому что ARM и FPGA работают на разных частотах.
Мой сценарий
resetTimer();
startTimer();
for(i=0; i<1000; i++) {
T1 = readTimer();
writeToFpgaIP(int* regAddress, int data);
T2 = readTimer();
storeInArray(T2-T1);
}
StopTimer();
latency = sum (array_write_timing[]) / 1000;
-*-*-*-End algo-*-*-*
В зависимости от задействованных интервалов времени (мсек, микросекунд, наносекунд) вы можете потерять гранулярность в вызовах readTimer. Более точный способ — использовать аппаратный зонд и осциллограф. Установите высокую контрольную точку при входе в подпрограмму writeToFPGA и низкую при выходе. Более новые области могут усреднить ширину импульса для вас, но даже если у вас нет такой возможности, вы увидите абсолютное время и почувствуете изменчивость.
Измените свой алгоритм так, чтобы он был более точным,
resetTimer();
startTimer();
T1 = readTimer();
for(i=0; i<1000; i++) {
writeToFpgaIP(int* regAddress, int data);
}
T2 = readTimer();
StopTimer();
latency = (T1-T2) / 1000;
Вы можете попытаться измерить издержки цикла, создав еще один цикл, который имитирует существующий цикл и рассчитывает его время. Например, если writeToFpgaIP
это функция,
dummyCall(int* regAddress, int data){}
dummyWrite(int* regAddress, int data){volatile int foo = data;}
dummyCall
это просто посмотреть накладные расходы вызова функции компиляторов и dummyWrite
сравнивать шину FPGA с вашей основной памятью (или кешем).
Изучите ассемблер, чтобы убедиться, что компилятор не оптимизировал его, и дважды проверьте, что он похож на цикл тестирования. Возможно, вам придется поработать с параметрами компилятора, чтобы цикл с dummyCall
(или же dummyWrite
) структурирован так же, как writeToFpgaIP
,
Использование осциллографа выгодно, но оно будет измерять только синхронизацию на стороне FPGA. Вы не можете охватить то, что происходит с данными после того, как они попадут на контакты CPU / SOC. Таким образом, использование обоих методов может быть полезным; убедитесь, что они подтверждают друг друга.
Если нет, то для улучшения доступа к порту / шине, к которой вы подключаете ПЛИС, может потребоваться некоторое исследование на стороне ARM.
Независимо от того, как реализованы вызовы readTimer () (это может быть простое чтение локального периферийного устройства), ваш тест, как написано, чередует критическую запись с другой обработкой. В зависимости от ядра, это может показать один цикл (для STR). К тому времени, когда цикл возобновляется, возможно, что STR завершен.
маловероятно, что ваш тест представляет собой реальную проблему, которую вы пытаетесь решить. Даже если вы повторяете STR в цикле 1000 раз, вы все равно не наблюдаете фактическую задержку, теперь вы смотрите на пропускную способность потоковой передачи на FPGA, что возможно.
В зависимости от системы задержка означает, насколько быстро (из определенного события) ядро может инициировать ответ в FPGA. Классически это может быть IRQ, передача некоторых данных в ПЛИС, возврат ответа, запись на периферийное устройство (если только ПЛИС не управляет контактами).
Немного лучшим подходом может быть запись данных в FPGA, считывание регистра FPGA (энергозависимый, область устройства), использование данных и их зацикливание.
В зависимости от системы памяти устройства это все еще может не дать результата, который связан с производительностью системы (например, Cortex-R8, Cortex-M0 будут в очень разных системах).
Вместо того, чтобы использовать внешний прицел или логический анализатор, я склонен добавлять измерение производительности в ПЛИС. Таким образом, я могу измерить общее и среднее количество циклов для обработки запросов от ЦП, а также измерить нагрузку на ЦП, выполняя взаимные запросы и измеряя общее количество прошедших циклов. Я также часто измеряю количество данных, передаваемых в любом направлении.