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

Указатель на невыровненную память

Даяв от тоже думал, почему так долго память ровняют, а оказалось что давноу же инт маин войд обсуждают...

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


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

7 minutes ago, EdgeAligned said:

Даяв от тоже думал, почему так долго память ровняют, а оказалось что давноу же инт маин войд обсуждают...

Видимо огромное количество знаний не даёт найти дорогу в трёх соснах.

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


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

20 hours ago, jcxz said:

Это ваш компилятор "не любит". А не си++.

GCC тоже может эти атрибуты.  Вопрос был в том, чтобы без всякой мишуры писать void main(void).

 

Столкнулся с тем, что если в функции memcpy адрес источника и/или приёмника не выровнен на 4, то используется функция memcpy с побайтовым копированием(или комбинированное копирование по типу 4+4+4+... остаток по 1 байту).

Это в некоторых случаях приводит к неправильной работе программы - именно, когда память не кеширована и требует чтения-записи из/в неё порциями по 2 или 4 байта. При этом адреса кратны 2 и можно копировать полу-байтами.

Пока вопрос закрыл так:

void memcpy2(u16 *d,u16 *s,u32 n)
{
 n>>=1;
 while(n--)*d++=*s++;
}

 

Можно ли GCC как-нибудь указать чтобы при выровненных адресах на 2 - копировал полу-словами? Для 4 - есть __abi_memcpy4().   Для 2 - не нашёл.

 

P.S. Не всегда возможно использовать выровненные адреса.  Например, для кодека Рида-Соломона GF(2^16) общая длина составляет 65535 полу-слов, проверочные символы к примеру - 512 полу-слов.   Смещение проверочных символов будет:   65535-512 = 64023-е полу-слово - это  130046 байт (адрес кратен 2). Хотя при этом адрес общего буфера может быть выровнен.

Изменено пользователем repstosw

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


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

А почему бы не использовать DMA Mem-to-Mem для копирования? Ему важно только чтобы начало структуры было выровнено, а остальное будет скопировано безотносительно структуры по 1, 2 или 4 байта, в зависимости от настроек.

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


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

40 minutes ago, EdgeAligned said:

А почему бы не использовать DMA Mem-to-Mem для копирования? Ему важно только чтобы начало структуры было выровнено, а остальное будет скопировано безотносительно структуры по 1, 2 или 4 байта, в зависимости от настроек.

У процессоров Allwinner DMA работает на тактовой частоте 200 МГц.  Производительность не сильно высокая.  С помощью инструкций NEON копирование память-память самое быстрое (но оно требует 64-байтного выравнивания)

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


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

10 часов назад, repstosw сказал:

GCC тоже может эти атрибуты.  Вопрос был в том, чтобы без всякой мишуры писать void main(void).

Если под "мишурой" Вы имеете в виду префиксы "__noreturn __task ", то они не обязательны (просто я пишу их везде для main() чтобы компилятор не лепил к ней ненужный эпилог/пролог функции). Никто не мешает писать без них - и без них void main() прекрасно компилируется в IAR.

10 часов назад, repstosw сказал:

Столкнулся с тем, что если в функции memcpy адрес источника и/или приёмника не выровнен на 4, то используется функция memcpy с побайтовым копированием(или комбинированное копирование по типу 4+4+4+... остаток по 1 байту).

Вобщем-то так было всегда. И это зависит от типа CPU: для каких-то CPU там поболее чем 2 варианта.

И о каком ядре вообще речь?

Для ядер >= Cortex-M3 для невыровненного копирования как правило используется пословное копирование (32 битными словами, но с использованием только команд LDR/STR), а для выровненного - командами LDMIA/STMIA по несколько регистров за раз (по крайней мере так делает memcpy() стандартной библиотеки IAR).

А по-байтное копирование - должно использоваться только для ядер, не поддерживающих невыровненный доступ на аппаратном уровне (типа ARM7/ARM9, Cortex-M0, ...). Там (насколько помню) memcpy() IAR может и полусловами копировать (проверив младший бит адресов).

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


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

20 minutes ago, jcxz said:

И о каком ядре вообще речь?

Xtensa HiFi4 DSP.    DATA RAM 0/1.   Хочет чтение-запись по 2 или 4 байта.   Чтение этой памяти другим ядром ARM Cortex A7 по 1 байту приводит к непредсказуемому результату (мусор).

Если кеш включить, то можно читать писать как угодно.  Но для межпроцессорного взаимодействия я отключил кеш для этих регионов памяти. Чтобы не перегружать инвалидациями и райтбэками.

23 minutes ago, jcxz said:

Если под "мишурой" Вы имеете в виду префиксы "__noreturn __task ", то они не обязательны (просто я пишу их везде для main() чтобы компилятор не лепил к ней ненужный эпилог/пролог функции). Никто не мешает писать без них - и без них void main() прекрасно компилируется в IAR.

То что компилируется, это понятно.  Речь была о ворнингах

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


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

On 10/25/2023 at 12:19 PM, repstosw said:

Xtensa HiFi4 DSP.    DATA RAM 0/1.   Хочет чтение-запись по 2 или 4 байта.   Чтение этой памяти другим ядром ARM Cortex A7 по 1 байту приводит к непредсказуемому результату (мусор).

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

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


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

15 minutes ago, sasamy said:

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

DSP пишет-читает по этим адресам память:

#define FEC_CODER_DATA      0x00420000
#define FEC_DECODER_DATA    0x00440000

А CPU читает соответственно вот эти адреса:

#define FEC_CODER_DATA      0x00038000
#define FEC_DECODER_DATA    0x00040000

Фактически  - это одни и те же ячейки памяти, просто разные дешифраторы адресов.

Кеши и буферы все отключены - и на DSP и на CPU.

CPU при попытке прочитать байт - получает не то, что на самом деле.   Если со стороны CPU включить кеш, то всё нормально.  Или не включать кеш, а читать полу-словами или словами (по 2- или 4- байта)

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


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

19 минут назад, sasamy сказал:

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

Чисто теоретически вполне может быть, что чтение байтами запрещено, но врядли такое может быть для ОЗУ.

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


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

On 10/25/2023 at 12:49 PM, repstosw said:

Фактически  - это одни и те же ячейки памяти, просто разные дешифраторы адресов.

сейчас понял - это sram а не ddr

https://github.com/YuzukiHD/FreeRTOS-HIFI4-DSP/issues/5

 

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


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

56 минут назад, repstosw сказал:

То что компилируется, это понятно.  Речь была о ворнингах

Нету их. Вообще.

25 минут назад, Arlleex сказал:

Чисто теоретически вполне может быть, что чтение байтами запрещено, но врядли такое может быть для ОЗУ.

У DSP-ядер частенько вообще нет инструкций для по-байтного обращения к памяти. У некоторых ядер - минимум можно словами читать/писать. Но у ARM должны быть по-байтные операции.

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


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

7 minutes ago, sasamy said:

сейчас понял - это sram а не ddr

https://github.com/YuzukiHD/FreeRTOS-HIFI4-DSP/issues/5

Так мой вопрос был не в том, что это такое и почему.   А в том, что как заставить компилятор memcpy() преобразовывать в чтение-запись полу-слов.

 

На счёт issues на github - непонятно, чем он это собирается выправлять?  Сам DSP прекрасно работает даже с интерливнутой памятью, потому что она для него своя и без разницы как оно там перекручено всё.  Проблемы приходят, когда CPU начинает  с этой памятью работать.

Вот именно по этой причине - я не люблю const data хранить в регионах SRAM, и храню их в IRAM, а потом в сишном стартапе их копирую.

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


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

On 10/25/2023 at 1:16 PM, repstosw said:

Так мой вопрос был не в том, что это такое и почему.   А в том, что как заставить компилятор memcpy() преобразовывать в чтение-запись полу-слов.

написать на асме - какой смысл бороться с компилятором

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


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

3 часа назад, jcxz сказал:

Но у ARM должны быть по-байтные операции.

Я немного о другом: на уровне имплементации AMBA-шины AHB-мосты могут дублировать/удалять данные на соответствующих байт-лэйнах.

Как пример: в STM32F-каком-то там к регистрам периферии APB нельзя лезть байтовыми и полусловными доступами, т.к. AHB-APB мост не передает информацию о разрядности доступа и принудительно дублирует байт-лэйны на запись и чтение, чтобы доступ был все равно 32-битным. Поэтому иногда и выходят "казусы" в виде "писал байт в младшую часть регистра GPIO, а он оказался еще и в соседних трех".

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


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

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...