ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Вторник
23 июля
1204769 Топик полностью
VladislavS. (01.05.2022 08:05, просмотров: 243) ответил LightElf на Суть моего спича кагбэ в том, что даже на мелких кортексах выигрыш в количестве команд не всегда приводит к выигрышу в реальной производительности. И раз уж мы не знаем точную модель, то не знаем и как там флеш устроен. Потому, считаю, утверждать "так быстрее чем эдак" несколько преждевременно.
Ну это же всё легко проверяется. Берём Cortex-M0+, пишем в прерывании как у ТС код и смотрим листинги: 

Компилятор IAR распоследний, оптимизация по скорости. Считать будем только команды работы с массивом. Отправка данных по назначению во всех случаях одинакова. Результаты ожидаемы. И, как ни странно, чтений данных из FLASH (код не считаем) во всех вариантах одинаковое количество. Так как Cortex-M0+ достаточно простая и прямолинейная архитектура, разница в скорости выполнения кода работы с массивом до двух раз видится. Если считать всё прерывание, то ближе к полутора, на глаз.


1. Связный список

void SysTick_Handler()
{   
  static auto *p=list.node;
  GPIOA->IDR=p->data.x;
  p=p->next;
}

//void SysTick_Handler()
//{   
//  static auto *p=list.node;
//  GPIOA->IDR=p->data.x;
SysTick_Handler:
        LDR      R0,??DataTable1_3  // Чтение из FLASH адреса p    (1)
        LDR      R1,[R0, #+0]       // Чтение из SRAM p            (2)
        LDR      R2,[R1, #+0]       // Чтение из FLASH data        (3)
        LDR      R3,??DataTable1_4  // Чтение из FLASH адреса IDR
        STR      R2,[R3, #+0]       // Запись data в IDR
//  p=p->next;
        LDR      R1,[R1, #+4]       // Чтение из FLASH нового p    (4)
        STR      R1,[R0, #+0]       // Сохранение p в SRAM         (5)
//}
        BX       LR

2. Инкремент индекса

void SysTick_Handler()
{   
  static auto i = 0;
  GPIOA->IDR=list.node[i].data.x;
  if(i<39) i++; else i=0;
}

//void SysTick_Handler()
//{   
//  static auto i = 0;
//  GPIOA->IDR=list.node[i].data.x;
SysTick_Handler:
        LDR      R0,??DataTable1_3    // Чтение из FLASH адреса i           (1)
        LDR      R1,[R0, #+0]         // Чтение из SRAM i                   (2)
        LDR      R2,??DataTable1_4    // Чтение из FLASH адреса node[0]     (3)
        LSLS     R3,R1,#+3            // Вычисление адреса node[i]          (4)
        LDR      R2,[R2, R3]          // Чтение из FLASH data               (5)
        LDR      R3,??DataTable1_5    // Чтение из FLASH адреса IDR
        STR      R2,[R3, #+0]         // Запись data в IDR
//  if(i<39) i++; else i=0;
        CMP      R1,#+39              // Сравнение на  конец массива        (6)
        BGE      ??SysTick_Handler_0  // Условный переход                   (7)
        ADDS     R1,R1,#+1            // Инкремент индекса                  (8)
        B        ??SysTick_Handler_1  // Накладные условного перехода       (9)
??SysTick_Handler_0:
        MOVS     R1,#+0               // Обнуление индекса                  (8)
//}
??SysTick_Handler_1:
        STR      R1,[R0, #+0]         // Сохранение i в SRAM                (10)либо(9)
        BX       LR 

3. Инкремент указателя

void SysTick_Handler()
{   
  static auto *p=list.node;
  GPIOA->IDR=p->data.x;
  if(p<(list.node+39)) p++; else p=list.node;
}

//void SysTick_Handler()
//{   
//  static auto *p=list.node;
//  GPIOA->IDR=p->data.x;
SysTick_Handler:
        LDR      R0,??DataTable1_3    // Чтение из FLASH адреса p           (1)
        LDR      R1,[R0, #+0]         // Чтение из SRAM p                   (2)
        LDR      R2,[R1, #+0]         // Чтение из FLASH data               (3)
        LDR      R3,??DataTable1_4    // Чтение из FLASH адреса IDR
        STR      R2,[R3, #+0]         // Запись data в IDR
//  if(p<(list.node+39)) p++; else p=list.node;
        LDR      R2,??DataTable1_5    // Чтение из FLASH адреса node[0]     (4)
        MOVS     R3,#+156             // Загрузка константы 39*sizeof(NODE) (5)
        LSLS     R3,R3,#+1            // Загрузка константы 39*sizeof(NODE) (6)
        ADDS     R3,R2,R3             // Вычисление адреса node[39]         (7)
        CMP      R1,R3                // Сравнение на конец массива         (8)
        BCS      ??SysTick_Handler_0  // Условный переход                   (9)
        MOVS     R2,R1                // Накладные условного перехода       (10)
        ADDS     R2,R2,#+8            // Инкремент указателя                (11)
//}
??SysTick_Handler_0:
        STR      R2,[R0, #+0]         // Сохранение p в SRAM                (12)либо(10)
        BX       LR