Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: разная скорость доступа к разным областям внешней SDRAM
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Ruslan1
Здравствуйте, уважаемые форумчане.
Столкнулся с нижеописанным эффектом.

система на 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)
   }

физически адреса "строк" массива:
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();

результат: скорость чтения из первых четырех строк примерно на 30% меньше чем из последних 4-х строк:
Нажмите для просмотра прикрепленного файла

Часть ячеек 0-й строки массива (до адреса примерно 0xC000F690) читается быстрее, потом все замедляется, а потом опять ускоряется.

Вопросы по вышеизложенному:
1.
Это просто демонстрация особенностей доступа к блокам SDRAM из разных задач (read-write-precharge плюс разные latency)?
Или нужно что-то в консерватории копать (некорректная инициализация, например)?
2.
Эффект устойчивый и объясняется даташитом SDRAM? и этим можно пользоваться, определив раз и навсегда "быстрые" и "медленные" блоки адресов SDRAM? Или скорость доступа все-таки зависит от предыстории использования, то есть как другие задачи лезут в память и какие адреса при этом использованы?

Все-таки если просто грамотным распределением массивов можно на 30% ускорить критические задачи, активно использующие SDRAM - это не хухры-мухры, можно и поковырять ради такого ускорения "из ничего".
0men
Дело точно не в СДРАМ. У меня контроллер памяти на циклоне, разницы в скорости доступа к разным банкам нет никакой
jcxz
Цитата(Ruslan1 @ Feb 5 2018, 12:00) *
Все-таки если просто грамотным распределением массивов можно на 30% ускорить критические задачи, активно использующие SDRAM - это не хухры-мухры, можно и поковырять ради такого ускорения "из ничего".

Вам вначале надо грамотно научиться код теста писать.
Как таким:
Код
        SET_DBG_PIN3;
        for(int n = 0; n < CNT; n++)
        {
            SET_DBG_PIN4;
            tmp32 = channelStorage[channel][n];
            CLEAR_DBG_PIN4;
        }
        CLEAR_DBG_PIN3;

можно вообще что-то тестировать??? У Вас скорость этого "кода" наверное только процентов на 10 зависит от скорости доступа к SDRAM. Всё остальное - от кучи прочих команд в теле цикла.
Таким "кодом" Вы меряете какие-то флуктуации температуры на Солнце.
Для того, чтобы что-то измерить, нужно вначале убрать все случайные факторы, не относящиеся к результату или максимально уменьшить их воздействие:
1. Тест должен быть написан на ассемблере.
2. Соотношение количества операций доступа к SDRAM к количеству прочих операций в цикле измерения должно быть максимальным. Т.е. - цикл должен состоять из множества LDMIA Rx,{...} максимальной длины (LDMIA R0!,{R1-R12,LR}). А ещё лучше: POP {R0-R12,LR}.
3. Тело цикла должно быть в ОЗУ (внутренней, CCM например) или заведомо в кеше FLASH. По выровненному адресу.
4. Необходимо учесть влияние кешей SDRAM (выключить их или построить цикл таким образом, чтобы они не влияли (например - сброс кеша в начале цикла и инкрементирование адреса в процессе)).
5. Измерять время нужно по любому внутреннему таймеру.
6. Прерывания и DMA и прочая активность - должны быть запрещены.
Ruslan1
Цитата(jcxz @ Feb 5 2018, 14:28) *
Вам вначале надо грамотно научиться код теста писать.
....
Для того, чтобы что-то измерить, нужно вначале убрать все случайные факторы, не относящиеся к результату или максимально уменьшить их воздействие:


Согласен, что эксперимент "очень грязный" и показывает не быстродействие SDRAM, а быстродействие SDRAM в моей программе.

Система используется давненько, и никаких потерь или искажений данных не замечено, то есть я как-то и не думал что может быть что-то накосячено в конфигурации SDRAM.

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

Только сейчас дошло, что на самом деле, у меня такая картина: буферы A1,2,3 активно читаются одновременно другими задачами. То есть все 8 буферов пишутся одной задачей, а вот дальше идет асинхронное чтение из них разными задачами, причем активно используются именно три буфера, показывающие минимальную скорость общения.
Сейчас с кэшем поиграюсь....


Upd: А как мне кэш выключить? И вообще что там есть кэш при конкретно доступе к SDRAM? Кроме как "Burst read" ничего не вижу.
0men
Цитата(Ruslan1 @ Feb 5 2018, 16:38) *
Только сейчас дошло, что на самом деле, у меня такая картина: буферы A1,2,3 активно читаются одновременно другими задачами. То есть все 8 буферов пишутся одной задачей, а вот дальше идет асинхронное чтение из них разными задачами, причем активно используются именно три буфера, показывающие минимальную скорость общения.
Сейчас с кэшем поиграюсь....

Upd: А как мне кэш выключить? И вообще что там есть кэш при конкретно доступе к SDRAM? Кроме как "Burst read" ничего не вижу.


Возможно, когда буферы пишутся, контроллер сдрам пишет их, используя бурст, это самый быстрый доступ. При асинхронном чтении (записи) все значительно медленнее.
jcxz
Цитата(Ruslan1 @ Feb 5 2018, 15:38) *
Upd: А как мне кэш выключить? И вообще что там есть кэш при конкретно доступе к SDRAM? Кроме как "Burst read" ничего не вижу.

Не знаю. Я это говорил касательно теста скорости. Выключить или сбросить - что доступно.
Даташит STM32F429 говорит: "Cacheable Read FIFO with 6 x32-bit depth (6 x14-bit address tag) for SDRAM controller."
Так что перед тестом скорости какого-то региона SDRAM, я бы прочитал не менее 6*32 бит из любого другого региона. Или на всяк случай побольше. И после сделал __DSB().
Golikov A.
Надо включить MPU и задать атрибуты региону на запрет кеширования и все такое, есть вероятность что СТМ периферия правильно отработает эту ситуацию.
картошка
А адреса строк по физическому ROW не дробятся длиной тестового пакета в первой половине таблицы тестируемых адресов ?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.