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

Как принято описывать разные типы данных для MK/CPU у одного и того же алгоритма?

Добрый день,

 

где-то с 3-4 года назад перешел на С++ и заметил за собой, что переписал почти все свои функции на template

template<typename DT, typename IT> DT func(DT *Arg1, int Arg2, IT *Arg3);

и в головной запускалке на обычном компьютере в качестве аргументов типов в DT подставляю double, и в IT подставляю int, а на микроконтроллерах в DT подставляю float, и в IT подставляю char или short.

 

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

 

Понятно, что так ввод-вывод отладить нельзя, я говорю только о алгоритмах, которые получают какие-то данные, что-то с ними делают и возвращают какой-то результат.

 

Меня удивляет то, что у меня это почти основной стиль программирования теперь - то есть почти все функции теперь стали в template.

 

Скажите, пожалуйста, а так принято?, а у вас также?

 

Спасибо!

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


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

16 minutes ago, iiv said:

...переписал почти все свои функции на template

У всех свои заскоки :dirol:

Я лично предпочитаю "стандартные" простые типы, предлагаемые разработчиками плюсовых компиляторов, например: uint32_t, int8_t и т.п

Если нужно внутри класса объявить свой более удобочитаемый тип, то вставляю внутри класса такие конструкции (пример) : using MyTypeName = uint16_t;

 

зы тема видится сугубо холиварной, срачи приветствуются ))

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


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

23 minutes ago, Forger said:

Я лично предпочитаю "стандартные" простые типы, предлагаемые разработчиками плюсовых компиляторов, например: uint32_t, int8_t и т.п

Спасибо Forger за ответ и, особенно за идею про using ! Полностью с вами согласен про стандартные типы uint32_t, uint8_t, но я как раз имел ввиду тот факт, что допустим алгоритм, реализованный в функции можно использовать с очень большими числами (там и unit64_t может не хватить) и с маленькими, где int8_t за глаза. Хочется один раз отладить и потом использвать везде где не попадя, но уже в каждом конкретном случае и архитектуре подставляя соответствующий тип. У меня такой зоопарк с архитектурами сейчас, что хочется как-то стандартизировать все это, чтобы по много раз не переписывать. С меня хватило того, что я портировал свои старые наработки с фортрана и С на С++ - там было около 250 тыс строк кода и во время портирования все пришлось заново перетестировать. Хочется избежать портирования софтвера при появлении новомодных типов, которые используются в компьютервижионе по типу двубайтового числа с плавающей точкой.

 

 

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


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

16 minutes ago, iiv said:

Хочется избежать портирования софтвера при появлении новомодных типов

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

 

17 minutes ago, iiv said:

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

Закрыть все вариации невозможно, да и не нужно. Реализуйте лишь тот функционал, которым реально пользуетесь.

Допиливать "алгоритмы" по ходу их применения в различных проектах все равно придется. Это нормально и неизбежно.

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

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


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

Есть такая библиотека VOLK из пакета GnuRadio где в зависимости от архитектуры процессора на котором это дело выполняется подставляются разные куски кода SIMD-ассемблерных вставок под обработку различных векторных сигналов.

Можете подглядеть что там наворочено.

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


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

2 часа назад, iiv сказал:

а на микроконтроллерах в DT подставляю float, и в IT подставляю char или short.

Когда пытаются изобрести универсальный снего-, болото-ход и чтобы ещё и по асфальту ездил, то обычно получается монстр, который и в болоте еле бултыхается и в снег проваливается и асфальт портит. И топлива жрёт как не в себя. Любое универсальное решение как правило - хуже специализированного. Это аксиома.

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


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

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

. . . .

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

. . . .

Если это существенно сокращает дублирующийся (до 99%) код, и его много, то все правильно. Это даже без "специфики" применения шаблонов для ООП.

Для отладки кода микроконтроллера на "инструментальном" PC скорее не шаблоны, а условная компиляция с подключением "специфических" h-файлов.

-------

Имел "счастье" разбираться в коде (ООП) где программист-ка применяла templete там где надо и где не надо в трехэтажном/вложенном формате. Аргументация была "шаблоны надо применять всегда". Читабельность кода была ниже плинтуса. Целью ставилось легкое и прозрачное добавление новых объектов (удалЕнные приборы учета с индивидуальными протоколами связи-обмена ).

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


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

Огромное всем участвующим и сочувствующим спасибо!

 

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

 

1 hour ago, jcxz said:

Когда пытаются изобрести универсальный снего-, болото-ход и чтобы ещё и по асфальту ездил, то обычно получается монстр, который и в болоте еле бултыхается и в снег проваливается и асфальт портит. И топлива жрёт как не в себя. Любое универсальное решение как правило - хуже специализированного. Это аксиома.

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

 

Вот например, у меня есть пакет итерационных методов решения линейных систем и задач минимизации. Пакет довольно развесистый, и разрабатывается с 1993 примерно года. Изначально был на фортране, в 1999-2001 я его переписал на С99 стандарт, недавно я его перепортировал на С++. На фортране этот монстр дублировал функциональность для четырех вариантов (float, double, complex float, complex double), на С99 это все было реализовано через define что с одной стороны, повышало читаемость, но, с другой стороны, все-таки define на тип - это все-таки не совсем классно. В современном варианте все это сделано через template, то есть что хочешь подставляй, с тем и будет работать. Читаемость слегка повысилась, удалось это объединить с отдельно стоящим вариантом этой же библиотеки для CUDA и OpenCL - раньше это было отдельным куском кода, а теперь все в одном.

 

То есть по сути получилось, что код теперь нигде не дублируется, есть элегантная возможность поддерживать как нативные float, double, complex float, complex double, так и некоторые специализированный конструкции, когда например, двойная точность реализована через пару чисел с одинарной точностью - такая конструкция очень хорошо ложится на МК, у которых нет аппаратного double, а компилер не умеет это делать с реалистичной скоростью. А, да, удалось еще и целочисленные индексы засунуть в темплейты, в некоторых архитектурах ведь они достигают до 8 байт (64 битные да и когда матрицы большие, \(10^{11}\) неизвестных в разреженной матрице я не раз решал) а в некоторых (как в МК) и 2 байт хватает.

 

То есть я много раз слышал, что template - это зло, но вот конкретно в этом случае, а также еще в нескольких других моих библиотеках, которые я поддерживаю 20+ лет, это повысило читабельность кода, удалило дублирование кода, уменьшило объем кода, и не изменило скорость работы алгоритмов.

 

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

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


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

16 minutes ago, iiv said:

То есть я много раз слышал, что template - это зло

В том то и дело - опираетесь на слухи, чужие мнения.

Template - это лишь инструмент, которым в неумелых руках можно натворить немало неприятностей. Но и наоборот.

В данном случае (в вашем случае) никто кроме вас не знает ваш код и что вы хотите сделать. Чтобы помочь, недостаточно лишь подобного абстрактного описания. Кстати, чем конкретно тут можно помочь? Разве что "накидать на вентилятор" ))

Но, может, тут все банально просто: вы лишь хотите поделится некими успехами в этом плане? Но пока что это выглядит несколько ... неуклюже ))

Короче, показывайте конкретный код (куски), что вас в них не устраивает но вы не знаете как это исправить. Больше конкретики )

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


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

3 minutes ago, Forger said:

Кстати, чем конкретно тут можно помочь? Разве что "накидать на вентилятор" ))

Но, может, тут все банально просто: вы лишь хотите поделится некими успехами в этом плане? Но пока что это выглядит несколько ... неуклюже ))

Спасибо большое, Forger,

 

иногда накидывание на вентилятор помогает понять в каком направлении двигаться.

 

Почему я это решил пообсуждать. Опыта с С++ сильно большого нет, то есть я не сторонник совсем всего новомодного и очень со скрипом (то есть с мануалом) знаю все детали даже С++17.

 

Есть большой пакет софта, который я много лет развивал и поддерживал где-то с 1993. Мне всегда очень жалко что-то переписывать, так как это необходимо еще и отлаживать. Когда я что-то в 90-х писал, я даже не предполагал, что буду этот пакет так долго использовать - тогда мысли были, что мир меняется очень быстро.

 

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

 

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

 

То есть у меня есть какие-то сомнения, что я что-то сделал не идеально, но не могу их разумно сформулировать. Ведь я же мог еще в 2000 году вместо С99 использовать те же темплейты на С++, но почему-то не додумался это сделать.

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


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

Честно, лень читать "простыни текста". Давайте ближе к делу.

5 minutes ago, iiv said:

но не могу их разумно сформулировать

Не торопитесь, никто не гонит ))

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


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

Спасибо большое, Forger, за ответ!

 

Ключевой вопрос у меня - какой стиль написания на С++ использовать, чтобы

1. алгоритмы можно было быстро без бубнов компилировать на разных архитектурах с разными длинами слов и разными размерами индексов,

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

3. производительность не потерять.

То есть подходит под этот стиль template с типами typename, или есть какие-то еще более нативные в С++ конструкции для такого рода разработки?

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


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

2 hours ago, iiv said:

1. алгоритмы можно было быстро без бубнов компилировать на разных архитектурах с разными длинами слов и разными размерами индексов,

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

 

2 hours ago, iiv said:

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

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

 

2 hours ago, iiv said:

3. производительность не потерять.

"На сосну залезть и зад не ободрать"? - Это миф. Всегда приходится идти на компромиссы.

 

2 hours ago, iiv said:

То есть подходит под этот стиль template с типами typename, или есть какие-то еще более нативные в С++ конструкции для такого рода разработки?

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

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


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

Для портов всего проекта (модуля, библиотеки) на другие архитектуры проще использовать typedef и препроцессор, а template нужны когда в пределах одного проекта необходимы разные инстансы одного шаблона (один алгоритм на разных типах).

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

Плавающая точка добавляет много особенностей которые надо помнить, даже без вариативности типов. У вас есть например такая шаблонная функция hypot? быстрая и безопасная во всем диапазоне подставленного типа?

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


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

Я считаю, что к универсализации надо подходить умеренно.

Да, на каждом углу сейчас гуру программирования на ЯВУ (например, на C++) порой тащат монстров из паттернов ООП для банального моргания лампочкой. Тут что-то личное, видимо. Каждый удовлетворяет себя по-своему, ИМХО. Однако только свое видение поможет разобраться и отделить мух от котлет. Я, например, если точно уверен, что некий кусок кода/алгоритм/драйвер целиком будет "гулять" из проекта в проект, конечно же напишу его более-менее универсально, если это будет позволительно по, например, скорости. Нет, я не буду описывать миллионы шаблонов, в которых спустя год и сам запутаешься. Я, при необходимости, просто допишу то, что мне требуется прямо сейчас. Практика показывает, что как бы ты ни универсалиизровал, получив на выходе огромного монстра, этот монстр в твоем очередном проекте все равно заставит тебя лезть ему под капот и дорабатывать. Умеренность, она в том, что при разработке алгоритма с потенциалом переиспользования где-то еще, мы заглядываем в будущее "на чуть чуть". Вот, например, пишем драйвер UART для консоли под МК: сразу можно определить механизмы задания скорости, параметров символа, да тех же GPIO-шек. Все остальное (особенно, если это будет что-то гиперкрутое и не стандартное) - "в следующий раз", когда пригодится. Ну а всякие шаблоны и наследования в C++ должны только этому и способствовать.

Именно поэтому всякие мастадонты типа бустов или stl-ов - многолетне развивающиеся (именно -СЯ) проекты, и что самое главное - итеративно развивающиеся. Если посмотреть на их историю, они иногда все перечеркивали и начинали сначала. Потому что получалась каша.

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


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

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

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

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

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

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

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

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

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

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