Жажда скорости — ARM или RISC-V?

3ca01b5a4ff17d379869b64ecf5a0af2.png

В этой короткой заметке я попытаюсь сравнить три разных микроконтроллера по времени реакции на внешнее прерывание. Дело это интересное, просто потому что иногда микроконтроллер должен реально контролировать и желательно по-быстрее. Ну и конечно, хочется оценить работу шины, прерываний и всего остального.

Итак, схема опыта очень проста — будем использовать 3 первые пина порта GPIOA, первый как источник внешнего прерывания (exti0), а 1 и 2 для вывода данных. Хватило бы и одного, но тогда осциллограф, как понимаете, подключать не так удобно -, а на скорости кода это не сказывается. Первый пин и второй, естественно, соединим проводком…

Будем подавать на второй пин высокий уровень, это вызовет прерывание, сработает обработчик. В нем будем просто выводить 0 на все пины порта GPIOA -, а по факту на второй и третий, получается. И цикл повторяется. Код примерно одинаков и для ARM и для RISC-V и приведен ниже.

Да, для опытов у нас будет два процессора ARM, обе stm — так уж вышло, они были под руками — stm32f103 и stm32h750, соответственно, первую запустим на 64 МГц, а вторую на 400 МГц (ну на шине будет всё равно 200 МГц). А вот для RISC-V попалось изделие WCH-IC, а именно ch32v307 и он будет у нас на 144 МГц. Кстати, в нем реализовано железячное переключение при прерывании с сохранением регистров, так что если постараться, то можно несколько еще ускорить код, выбросив пару-тройку тактов.

Однако для эксперимента компилятор был использован с одной и той же опцией оптимизации -Os и никаких трюков не применялось. Код на ассемблере получился примерно похожий, с ньюансами, конечно, но всё же…

Итак, сам код

// это код обработчика для ARM
void EXTI0_IRQHandler(void) {
    __HAL_GPIO_EXTI_CLEAR_IT(1);
    GPIOA->ODR = 0;
}

// а это для RISC-V
void EXTI0_IRQHandler(void)
{
    EXTI->INTFR = EXTI_Line0;
    GPIOA->OUTDR = 0;
}

// ну а это код выполняется в главном цикле
  for(;;) {
          GPIOA->ODR = 6;
          __NOP(); // и так далее примерно 100 раз
        ...
  }

Для замеров использовался осциллограф с 1 Gsps, что дает разрешение в 10 нс — вполне для наших целей подходящее. На экране, конечно, череда импульсов — ну это как и ожидалось.

Итак, вот замеры — еще раз подчеркну, что так как точность 10 нс (а цикл шины у h750 всё же 5 нс), то и число округлялись до десяток.

Микроконтроллер

stm32f103

stm32h750

ch32v307

Архитектура

ARM

ARM

RISC-V

частота шины, МГц

64

200

144

время импульса, нс

610

200

120

Итак, что жы мы видим? Ожидаемо на почти втрое большей частоте шины H750 имеет в три раза меньшее время. Но посмотрите -, а risc-v то при меньшей частоте шины дает вдвое меньшее время! Это очень интересно… А если еще и оптимизировать код, думаю, можно выдать еще на 10–15% меньшее время. Ну тут конечно, надо не забывать о скорости работы самого порта — у всех была выставлено максимальная скорость (это 40 МГц для ARM и 50 МГц для RISC-V), так что по этому параметру надо было бы округлять до 20 нс.

И всё равно, для «быстрых» приложений RISC-V, похоже всухую выигрывает у ARM. Если не согласны, напишите в комментариях, как говорится :)

© Habrahabr.ru