Перейти к содержанию

разная скорость доступа к разным областям внешней SDRAM

Здравствуйте, уважаемые форумчане.
Столкнулся с нижеописанным эффектом.

система на 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-х строк:
[attachment=110997:memtest1.jpg]

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

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

Все-таки если просто грамотным распределением массивов можно на 30% ускорить критические задачи, активно использующие SDRAM - это не хухры-мухры, можно и поковырять ради такого ускорения "из ничего".

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Дело точно не в СДРАМ. У меня контроллер памяти на циклоне, разницы в скорости доступа к разным банкам нет никакой

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата(Ruslan1 @ Feb 5 2018, 12:00) <{POST_SNAPBACK}>
Все-таки если просто грамотным распределением массивов можно на 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 и прочая активность - должны быть запрещены.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата(jcxz @ Feb 5 2018, 14:28) <{POST_SNAPBACK}>
Вам вначале надо грамотно научиться код теста писать.
....
Для того, чтобы что-то измерить, нужно вначале убрать все случайные факторы, не относящиеся к результату или максимально уменьшить их воздействие:


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

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

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

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


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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата(Ruslan1 @ Feb 5 2018, 16:38) <{POST_SNAPBACK}>
Только сейчас дошло, что на самом деле, у меня такая картина: буферы A1,2,3 активно читаются одновременно другими задачами. То есть все 8 буферов пишутся одной задачей, а вот дальше идет асинхронное чтение из них разными задачами, причем активно используются именно три буфера, показывающие минимальную скорость общения.
Сейчас с кэшем поиграюсь....

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


Возможно, когда буферы пишутся, контроллер сдрам пишет их, используя бурст, это самый быстрый доступ. При асинхронном чтении (записи) все значительно медленнее.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата(Ruslan1 @ Feb 5 2018, 15:38) <{POST_SNAPBACK}>
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().

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Надо включить MPU и задать атрибуты региону на запрет кеширования и все такое, есть вероятность что СТМ периферия правильно отработает эту ситуацию.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
А адреса строк по физическому ROW не дробятся длиной тестового пакета в первой половине таблицы тестируемых адресов ?
Изменено пользователем картошка

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
Авторизация