repstosw 18 17 октября, 2023 Опубликовано 17 октября, 2023 (изменено) · Жалоба Пишу задачу для второго ядра. Кодер Рида-Соломона. Данные в буфере. Они читаются в задаче, далее производятся манипуляции с данными, и они обратно читаются в тот же буфер. Эти данные использует другой процессор. Ядро другой архитектуры, не как архитектура первого ядра. И компилятор уже другой. На оптимизации -Ofast, компилятор выкидывает процедуру обработки данных. Справедливо полагая, что результат вычислений нигде не используется. Выкидывается функция encode_rs(RSC); void FEC_Encode(void) { if(rsc==0) { cache_inv_range((u32)RSC,((u32)RSC)+fsize); encode_rs(RSC); cache_flush_range((u32)RSC,((u32)RSC)+fsize); UART_putc('^'); rsc=1; //ready flag for first CPU } } Вопрос, как сделать так, чтобы код не выкидывался и выполнялся? Вариант вывести результат функции через printf() - не рассматривается. Изменено 17 октября, 2023 пользователем repstosw Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vov4ick 39 17 октября, 2023 Опубликовано 17 октября, 2023 · Жалоба extern volatile ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 27 17 октября, 2023 Опубликовано 17 октября, 2023 · Жалоба Если GCC, то __attribute__ ((used)) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexRayne 7 17 октября, 2023 Опубликовано 17 октября, 2023 (изменено) · Жалоба volatile и used - это все полумеры. сделайте функцию пустую (непременно глобальную), которой передайте аргументом результат обработки Изменено 17 октября, 2023 пользователем AlexRayne Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 180 17 октября, 2023 Опубликовано 17 октября, 2023 · Жалоба Квалифицировать некий RSC ключевым словом volatile, этого будет достаточно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tonyk_av 43 17 октября, 2023 Опубликовано 17 октября, 2023 · Жалоба 1 hour ago, AlexRayne said: volatile и used - это все полумеры Это не полумеры, а явное указание компилятору и линковщику не делать при оптимизации никаких предположений о способе использования переменных. Эти квалификатор и директива как раз и сделаны для случаев, подобных обработчикам прерываний и всяких многопроцессорных систем. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 17 октября, 2023 Опубликовано 17 октября, 2023 (изменено) · Жалоба 2 hours ago, vov4ick said: extern volatile ? vloatile сделал. Но это указатель. И ещё когда mamcpy, memset, то требует убрать volatile. Как сделать массив volatile? Чтобы компилятор имел ввиду - каждый элемент массива может быть volatile. Ну ещё и барьер памяти, потому что важна последовательность действий - вызов encode_rs() не раньше инвалидации и не позже flush. rsc=1 - в самом конце - это флаг другому ядру: void FEC_Encode(void) { if(rsc==0) { cache_inv_range((u32)RSC,((u32)RSC)+fsize); __asm__ __volatile__ ("" ::: "memory"); encode_rs(RSC); __asm__ __volatile__ ("" ::: "memory"); cache_flush_range((u32)RSC,((u32)RSC)+fsize); __asm__ __volatile__ ("" ::: "memory"); UART_putc('^'); __asm__ __volatile__ ("" ::: "memory"); rsc=1; //ready flag for first CPU } } rsc - это некешируемая ячейка памяти, хранящая флаг - volatile : оба ядра могут её читать-писать. RSC - указатель на буфер данных, тоже volatile. Изменено 17 октября, 2023 пользователем repstosw Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sasamy 0 17 октября, 2023 Опубликовано 17 октября, 2023 · Жалоба On 10/17/2023 at 5:03 PM, repstosw said: rsc - это некешируемая ячейка памяти, хранящая флаг - volatile : оба ядра могут её читать-писать. опять поллинг 🙂 там ведь есть аппапртные спинлоки с генерацией прерываний Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 180 17 октября, 2023 Опубликовано 17 октября, 2023 · Жалоба 1 час назад, repstosw сказал: Как сделать массив volatile? Чтобы компилятор имел ввиду - каждый элемент массива может быть volatile. u32 volatile buffer[10]; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 136 17 октября, 2023 Опубликовано 17 октября, 2023 · Жалоба 1 час назад, repstosw сказал: RSC - указатель на буфер данных, тоже volatile. Если сам указатель не меняется - ему совершенно незачем быть volatile. Он должен быть указателем на volatile. Вы бы показали его объявление, тогда вам бы посоветовали правильный вариант. 1 час назад, repstosw сказал: Как сделать массив volatile volatile int a1[10]; int volatile a2[10]; // эти два объявления эквивалентны, выбирайте по вкусу. int * pa; // указатель на int int * volatile pb; // volatile-указатель на int volatile int * pc1; // указатель на volatile int int volatile * pc2; // тоже указатель на volatile int int volatile * volatile pd; // volatile-указатель на volatile-int 1 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 236 17 октября, 2023 Опубликовано 17 октября, 2023 · Жалоба 1 час назад, repstosw сказал: И ещё когда mamcpy, memset, то требует убрать volatile. Тривиальное приведение типа спасёт предводителя дворянства и отца демократии от козней mamcpy. 1 час назад, repstosw сказал: rsc - это некешируемая ячейка памяти, хранящая флаг - volatile : оба ядра могут её читать-писать. RSC - указатель на буфер данных, тоже volatile. Барьер перед rsc=1, и сама запись - с volatile. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
amaora 24 17 октября, 2023 Опубликовано 17 октября, 2023 (изменено) · Жалоба 2 hours ago, repstosw said: __asm__ __volatile__ ("" ::: "memory"); В многопроцессорной системе барьеры вероятно посложнее делаются, здесь только для компилятора указания. Изменено 17 октября, 2023 пользователем amaora Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 180 17 октября, 2023 Опубликовано 17 октября, 2023 · Жалоба 30 минут назад, amaora сказал: вероятно 100% Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sasamy 0 17 октября, 2023 Опубликовано 17 октября, 2023 (изменено) · Жалоба On 10/17/2023 at 6:38 PM, jcxz said: Барьер перед rsc=1, и сама запись - с volatile. насколько я понял речь про t113-s3, там есть аппаратные спинлоки, достаточно просто прочитать его и если прочитал 0 значит твоё ядро захватило блокировку. Тут пример со стороны arm ядра https://elixir.bootlin.com/linux/latest/source/drivers/hwspinlock/sun6i_hwspinlock.c#L67 в readl есть барьер после чтения https://elixir.bootlin.com/linux/latest/source/arch/arm/include/asm/io.h#L286 для armv7 и выше он такой https://elixir.bootlin.com/linux/latest/source/arch/arm/include/asm/barrier.h#L20 volatile естественно но это тоже только для компилятора, от переупорядочивания вызовов в спекулятивных архитектурах он не спасёт на стороне ядра xtensa насколько я понял барьер не нужен Изменено 17 октября, 2023 пользователем sasamy Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 18 октября, 2023 Опубликовано 18 октября, 2023 (изменено) · Жалоба 9 hours ago, Сергей Борщ said: Если сам указатель не меняется - ему совершенно незачем быть volatile. Он должен быть указателем на volatile. Вы бы показали его объявление, тогда вам бы посоветовали правильный вариант. #define FEC_CODER_CONTROL 0x47E00000 //контроль кодера (не кеширован) #define rsc (*(volatile unsigned int*)FEC_CODER_CONTROL) #define FEC_CODER_DATA 0xC7D00000 //адрес буфера кодера (кеширован) volatile dtype *RSC=(volatile unsigned short*)FEC_CODER_DATA; 9 hours ago, Сергей Борщ said: volatile int a1[10]; int volatile a2[10]; // эти два объявления эквивалентны, выбирайте по вкусу. Это точно, что в этих случаях каждый элемент массива будет volatile? Или только имя массива? 9 hours ago, jcxz said: Тривиальное приведение типа спасёт предводителя дворянства и отца демократии от козней mamcpy. Так и сделал. 10 hours ago, sasamy said: опять поллинг 🙂 там ведь есть аппапртные спинлоки с генерацией прерываний В настоящий момент не до конца раскурил эти спинлоки. Они тормозят ядро? Тогда не подходит. То, что флаг установился/сбросился, это ещё недостаточно, чтобы тормозить ядро. Потому что оно кроме этого ещё некоторые вещи делает. 8 hours ago, amaora said: В многопроцессорной системе барьеры вероятно посложнее делаются, здесь только для компилятора указания. Для компилятора и предназначалось. Чтобы не переставил местами несвязанные между собой конструкции. Для DSP барьер памяти : memw, для CPU - инструкция DSB Изменено 18 октября, 2023 пользователем repstosw Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться