LINUX.ORG.RU

YAFL, много аргументов у функций, что делать?

 , , , ,


0

1

Привет, ЛОР!

Есть у меня вот такое поделие.

И есть в нём страшные места по типу:

Мне подобные места не нравятся потому, что аргументы выделяются на стеке, что в случае многопоточных имбедов не есть хорошо, ибо места на стеках потоков как правило мало, а память микроконтроллера не резиновая.

Хочется сэкономить память на стеках и (в идеале) не уронить производительность.

В первом случае можно для всех аргументов сделать поля в self, но для второго (если действовать по аналогии) уже придется создавать отдельную структуру для значений аргументов…

Встечались ли вы с подобными проблемами, и как решали их?

★★★★★

Последнее исправление: shkolnick-kun (всего исправлений: 1)

Я не настоящий сварщик, но разве static inline не заинлайнит эту функцию внутрь вызывающей?

Ну а в общем случае, какие альтернативы размещению данных в глобальной памяти/куче?

qaqa ★★
()
Последнее исправление: qaqa (всего исправлений: 1)
Ответ на: комментарий от qaqa

Я не настоящий сварщик, но разве static inline не заинлайнит эту функцию внутрь вызывающей?

Не всегда.

какие альтернативы

В моём случае:

  • стек;
  • глобальные переменные.

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

const yaflEKFBaseSt kf = YAFL_EKF_BASE_INITIALIZER(fx, jfx, hx, jhx, 0, NX, NZ, 0.0, 0.0, kf_memory);

В этом случае деcкриптор самого фильтра будет лежать в ROМ/FLASH. В оперативе будет только kf_memory.

Более того, почти все аргументы вызовов функций yafl_math.c из yafl.c вычисляются во время компиляции.

Т.е. либу можно переписать так, что функций типа yafl_ekf_base_update больше не будет, а будут просто циклы по константным массивам с вызовами функций по указателям с передачей им указателей на константные структуры с аргументаами…

В этом случае исползование оперативы ещё сократится…

shkolnick-kun ★★★★★
() автор топика
Последнее исправление: shkolnick-kun (всего исправлений: 3)
Ответ на: комментарий от LongLiveUbuntu

Передавать на вход в функцию константный указатель на экземпляр структуры.

Уже об этом подумал:

Более того, почти все аргументы вызовов функций yafl_math.c из yafl.c вычисляются во время компиляции.

Т.е. либу можно переписать так, что функций типа yafl_ekf_base_update больше не будет, а будут просто циклы по константным массивам с вызовами функций по указателям с передачей им указателей на константные структуры с аргументаами…

Но это - переписывание всей либы почти с нуля… Ибо архитектура меняется

shkolnick-kun ★★★★★
() автор топика
Последнее исправление: shkolnick-kun (всего исправлений: 1)
Ответ на: комментарий от shkolnick-kun

Немного не понял про память микроконтроллеров, но раз

Хочется сэкономить память на стеках и (в идеале) не уронить производительность.

попробуй реализовать в heap свой parameter stack, и передавать указатель на него в yaflKalmanBaseSt, там еще нужен будет указатель на stack top element размером 1 байт, при размере стека < 256, но это опционально. При этом прототипы функций вообще никогда не будут меняться при смене числа аргументов, можно будет передавать в функции переменное число позиционных параметров и не париться с отдельными структурами для аргументов, и возвращать переменное число результатов. Если хранить в стеке только указатели, то overhead составит размер стека * sizeof(void*) + sizeof(void*) + 1, что при размере стека 20 элементов на x64 равно 169 байт. Думаю это не так много, правда это сырой такой расчет. И надо будет подумать над многопоточностью.

spring
()
Ответ на: комментарий от spring

Немного не понял про память микроконтроллеров

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

Фактически, все эти «контексты» будут представлять собой константы, рассчитанные во время компиляции проекта.

И лежать они будут во FLASH/ROM (если нам повезло, и создатели компилятора не схалтурили, как в случае avr-gcc).

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

Соответственно, стеки разгружаются, прологи и эпилоги вызовов функций становятся «легче».

shkolnick-kun ★★★★★
() автор топика
Ответ на: комментарий от shkolnick-kun

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

Как это заинтерфейсить с Cython/Python для тестирования и прототипирования???

а вот это серьезный вопрос, ответ напрямую зависит от масштабов финансирования проекта.

spring
()