Столкнулся с нижеописанным эффектом.
система на STM32F429. Внешне подключена память SDRAM IS42S16400J : 1 Meg Bits x 16 Bits x 4 Banks (64-MBIT).
Есть динамически определенный через OS_Malloc() двумерный массив.
под стек выделен сегмент памяти:
Код
RW_RAM1 0xC0000000 UNINIT 0x00700000 {; external 512k x 16 bit (7M) RAM stack for FreeRTOS
*(.ram1)
}
*(.ram1)
}
физически адреса "строк" массива:
0- 0xC000F598
1- 0xC008F5A0
2- 0xC010F5A8
3- 0xC018F5B0
4- 0xC020F5B8
5- 0xC028F5C0
6- 0xC030F5C8
7- 0xC038F5D0
тестировал скорость чтения из разных строк простой программой:
Код
//testing of the memory speed
volatile uint32_t tmp32;
#define CHN 8
#define CNT 100
volatile void* tmpntArray[CHN];
taskENTER_CRITICAL();
for(int channel = 0; channel < CHN; channel++)
{
tmpntArray[channel] = &channelStorage[channel][0];
SET_DBG_PIN3;
for(int n = 0; n < CNT; n++)
{
SET_DBG_PIN4;
tmp32 = channelStorage[channel][n];
CLEAR_DBG_PIN4;
}
CLEAR_DBG_PIN3;
}
taskEXIT_CRITICAL();
volatile uint32_t tmp32;
#define CHN 8
#define CNT 100
volatile void* tmpntArray[CHN];
taskENTER_CRITICAL();
for(int channel = 0; channel < CHN; channel++)
{
tmpntArray[channel] = &channelStorage[channel][0];
SET_DBG_PIN3;
for(int n = 0; n < CNT; n++)
{
SET_DBG_PIN4;
tmp32 = channelStorage[channel][n];
CLEAR_DBG_PIN4;
}
CLEAR_DBG_PIN3;
}
taskEXIT_CRITICAL();
результат: скорость чтения из первых четырех строк примерно на 30% меньше чем из последних 4-х строк:
Нажмите для просмотра прикрепленного файла
Часть ячеек 0-й строки массива (до адреса примерно 0xC000F690) читается быстрее, потом все замедляется, а потом опять ускоряется.
Вопросы по вышеизложенному:
1.
Это просто демонстрация особенностей доступа к блокам SDRAM из разных задач (read-write-precharge плюс разные latency)?
Или нужно что-то в консерватории копать (некорректная инициализация, например)?
2.
Эффект устойчивый и объясняется даташитом SDRAM? и этим можно пользоваться, определив раз и навсегда "быстрые" и "медленные" блоки адресов SDRAM? Или скорость доступа все-таки зависит от предыстории использования, то есть как другие задачи лезут в память и какие адреса при этом использованы?
Все-таки если просто грамотным распределением массивов можно на 30% ускорить критические задачи, активно использующие SDRAM - это не хухры-мухры, можно и поковырять ради такого ускорения "из ничего".