ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Вторник
25 марта
1504090
petrd (07.03.2025 08:42, просмотров: 1492)
CH32V003. Смотрел на работу внутренностей, хотел посмотреть как работает предсказатель переходов и наткнулся на сопутствующее непонятное (для меня) поведение. 

Вот код, упростил до минимума, ничего полезного, простое ветвление if...else... Систик замеряет время исполнения. Меняю MIN и MAX, перекомпилирую, запускаю, смотрю отладчиком time_delta.

Ассемблерный код части, где идут замеры не меняется. Когда идет по одной ветви время 0x3b, по другой 0x39. Разница 2 такта, предсказатель работает.

Теперь непонятное. Меняю размерность массива c uiny16_t на uint8_t, в обьявлении функции тоже. Ассемблерная часть меняется, только несколько строк, различия в асм выделил.

И теперь после замеров цыфры стали другие, 0x36 и 0x38. Те же два такта, ходят по тем же ветвям, вроде логично. Но только теперь при прочих равных условиях большее и меньшее числа поменялись местами.

Как будто ветви переходов поменялись местами, но нет, они не поменялись. Почему? Что происходит? Не могу найти объяснения этому, а может глаз замылился.


#define ARRAY_SIZE 1
#define MIN 1 #define MAX 253 volatile uint32_t cnt_tick; volatile uint32_t dummy = 0; volatile uint32_t time_delta; volatile uint32_t start_time, end_time; volatile uint16_t unsorted_array[ARRAY_SIZE]; void SysTick_Init(void){ SysTick->SR = 0; SysTick->CNT = 0; SysTick->CTLR = 5; } uint32_t measure_time(volatile uint16_t *array, uint16_t treshold) { start_time = SysTick->CNT; for (uint32_t i = 0; i < ARRAY_SIZE; i++) { if (array[i] > treshold){ dummy++; } else { asm volatile("nop"); dummy--; } } end_time = SysTick->CNT; return end_time - start_time; } int main() { SysTick_Init(); for (uint32_t i = 0; i < ARRAY_SIZE; i++) { unsorted_array[i] = MIN; } while (1){ time_delta = measure_time(unsorted_array, 128); cnt_tick = SysTick->CNT; asm volatile("nop"); } }