C против C ++ во встроенном Linux

Разрабатываю приложение для встроенного Linux (ARM). Он будет выполняться 500 раз в секунду, поэтому важна скорость. Я бы предпочел использовать C ++, но боюсь, что он будет медленнее, чем C, даже если я буду избегать таких необычных функций, как виртуальные функции. Есть ли причина использовать C или так же хорошо писать на C ++?


person Gregory Khrapunovich    schedule 28.02.2011    source источник
comment
Виртуальной функции не следует избегать. Реализовать ту же функциональность в C вручную не будет быстрее, чем версия, созданная компилятором, а компилятор C ++ хорош в ее оптимизации, когда она не нужна.   -  person Martin York    schedule 28.02.2011
comment
@ Мартин прав. Для вызова виртуальных функций требуется всего одна или две инструкции, и если это действительно то, что вам нужно, вам все равно придется делать это на C.   -  person Mike Dunlavey    schedule 28.02.2011
comment
Вот несколько интересных статей по теме: stackoverflow.com/questions/2039444/   -  person Emile Cormier    schedule 28.02.2011
comment
Попробуйте использовать как C, так и C ++, а затем измерьте полученные двоичные файлы на встроенном устройстве. Если вы не хотите писать 2 версии приложения, просто используйте язык, который вам удобнее (C ++).   -  person pmg    schedule 01.03.2011


Ответы (8)


C ++ в целом не страдает от потерь времени выполнения по сравнению с C - (за исключением нескольких вещей, таких как RTTI).

За исключением нескольких странных обстоятельств, компилятор должен иметь возможность определять, какую виртуальную функцию вызывать во время компиляции, и поэтому не добавлять накладных расходов.

Изменить: Хорошо, с таким разнообразием компиляторов, процессоров, библиотек времени выполнения, ОС есть некоторые функции C ++, которые могут создавать более медленный код, есть некоторые функции, которые могут создавать более быстрый код.

Но можем ли мы все согласиться с тем, что C ++ больше не исключается автоматически из использования встраиваемых?

person Martin Beckett    schedule 28.02.2011
comment
Если вы используете C ++ как уродливый C (повсюду дополнительные приведения), то то, что вы сказали, верно. Но как только вы начнете использовать что-либо, что делает C ++ комфортным, накладных расходов будет намного больше, и их нельзя будет оптимизировать. - person R.. GitHub STOP HELPING ICE; 01.03.2011
comment
Виртуальные функции и шаблоны должны иметь нулевую стоимость. Исключение составляют нулевая стоимость, если не вызывается какой-либо достойный компилятор. Dynamic_cast обычно работает без RTTI - с некоторыми предупреждениями. Размер кода может быть проблемой, но это, конечно, зависит от того, что вы имеете в виду под встроенным. - person Martin Beckett; 01.03.2011
comment
Исключения имеют отрицательную стоимость, если вы можете удалить обработку ошибок C из обычного потока кода. Оптимизаторы могут легко оптимизировать для случая, не являющегося исключением, но они не знают, возвращает ли функция C 0,1 или -1 в случае ошибки. - person MSalters; 01.03.2011
comment
Я использую C ++ 11 и метапрограммирование на встроенном ARM с 32 КБ флэш-памяти! Я обнаружил, что если вы используете современный компилятор (я использую GCC 4.6), вы можете переносить код C на C ++ и иногда видеть уменьшение размера. constexpr - важный инструмент. - person odinthenerd; 28.06.2013
comment
Контейнеры STL (реализованные с помощью шаблонов) на самом деле являются огромным преимуществом, если в вашем коде есть какие-либо важные структуры данных. Реализации настолько хороши, насколько это возможно, и, вероятно, лучше, чем те, которые вы написали бы сами. Вы также можете выделить пул, если это необходимо. - person marko; 28.06.2013
comment
@MSalters +1 за это. Конечно, часто сравнивают, чтобы НЕ писать код обработки ошибок вообще, а не правильно (и протестировать? Да ... верно ..) обработку ошибок в C. RAII - это огромная победа с точки зрения правильности и проверяемости. - person marko; 28.06.2013

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

Я должен сказать больше. Метапрограммирование шаблонов и некоторые уловки наследования классов действительно удивительны. Это может сэкономить вам много времени на обработку, которое в противном случае вы бы потратили на «ifing» и «переключение».

Это означает, что C ++ может быть на самом деле быстрее, чем C.

Очевидно, что вы можете программировать «на C», используя C ++, и у вас вообще не будет никаких штрафов. Если вы не слишком любите C ++, я бы посоветовал вам сделать «C на C ++» или «C с расширениями C ++», просто чтобы воспользоваться улучшениями C ++, но реальное преимущество, которое вы получите, - это программирование C ++. способ. Там вы увидите, что C ++ , довольно часто, или быстрее, или чище, чем C, или, по крайней мере, так же быстро, как.

Не бойся. Face C ++. После stdc ++ (против libc) накладных расходов по размеру кода почти не будет. Если размер вашего приложения от среднего до большого, он будет разбавлен.

Я использую C ++ от простого 8-битного ATmega до ARM9 от Marvell, проходя через AVR32 UC3 и Cortex-M3, и всегда считаю это выгодным.

Если вам нужен конкретный совет в той или иной ситуации, не стесняйтесь спрашивать.

person j4x    schedule 01.03.2011
comment
Это тот ответ, на который я надеялся. На C ++ гораздо интереснее писать даже для таких простых вещей, как возможность объявлять переменную, когда она вам нужна (в отличие от начала блока в C). И, конечно, я предпочитаю инкапсуляцию классов глобальным функциям C. Я надеюсь избежать динамического выделения памяти или чего-то экзотического. - person Gregory Khrapunovich; 04.03.2011
comment
Преимущества C ++ во встроенном мире огромны. Я обнаружил, что __attribute ((always_inline)) является находкой, когда абстрактные интерфейсы компилируются в небытие и оставляют только более строгую статическую проверку важных вещей. - person odinthenerd; 28.06.2013

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

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

person Erik    schedule 28.02.2011
comment
Разница в размерах незначительна при условии, что версия C функционально эквивалентна версии C ++. Например, если версия C ++ использует наследование, версия C также должна кодировать эквивалент, без сокращений. По моему опыту, размер не является проблемой. - person Thomas Matthews; 28.02.2011
comment
@Thomas: это просто неправда, потому что большая часть загружаемого кода библиотеки будет иметь огромный расширенный набор необходимых функций, и компоновщик не сможет определить, какие части могут быть исключены. Статически свяжите программу C hello world с любой нормальной библиотекой C (любой из BSD, uClibc, Bionic и т. Д. - только не с glibc, stdio которой по существу написан на C ++) и сравните эквивалентную статически связанную программу C ++ с использованием iostream. - person R.. GitHub STOP HELPING ICE; 01.03.2011
comment
@R ..: если вы выберете подходящую реализацию libc, будьте честны и выберите в равной степени подходящий iostream. Дитмар Кюль доказал (около 10 лет назад), что Hello, World может быть меньше в C ++. Простая причина: компоновщик может исключить operator<<ostream&, float), но не case 'f': из реализации printf(). - person MSalters; 01.03.2011
comment
размер библиотеки (теоретически) может быть проблемой в некоторых средах, но в исходном вопросе упоминается встроенный Linux, поэтому это как минимум 32-битная система, а сама операционная система достаточно велика. Так что я сомневаюсь, что в данном случае размер имеет значение :) - person user396672; 01.03.2011
comment
В настоящее время я создаю встроенную систему на основе Linux, в которой я решил добавить на устройство больше флэш-памяти, чтобы иметь возможность включать динамические библиотеки C ++. Так что, по крайней мере, для меня размер был реальным фактором. - person Erik; 01.03.2011
comment
@Eric: Вы правы, это может произойти, если вся система почти точно умещается в памяти, я только подозреваю, что в таком случае вероятность относительно меньше (но не ноль, я согласен) - person user396672; 01.03.2011
comment
Существуют и другие встроенные реализации, кроме Linux или WinCE. Многие из этих компиляторов, Green Hills, Metaware, GNU, Arm, Intel и т. Д., Разрабатывают свои библиотеки для небольших систем. Некоторые даже предоставляют исходный код на тот случай, если вам нужно специализировать подпрограммы, например fwrite. Помните, что не на всех встроенных платформах есть консоли. - person Thomas Matthews; 01.03.2011
comment
@MSalters: недостаток вашего аргумента заключается в том, что код печати с плавающей запятой меньше минимальных накладных расходов, которые вы получите от других вещей в iostream, которые невозможно устранить. (Для точной печати с плавающей запятой требуется около 4-5 КБ кода, а неточная, но соответствующая реализация, вероятно, может быть всего 1,5-2 КБ.) - person R.. GitHub STOP HELPING ICE; 01.03.2011
comment
@R ..: Не могли бы вы объяснить, что это за неснижаемые накладные расходы? AFAICT это несколько байтов (даже не sizeof(streambuf)+sizeof(std::cout), потому что их можно комбинировать.) - person MSalters; 03.03.2011
comment
@MSalters: Давайте посмотрим на эмпирические значения. Пожалуйста, покажите мне программу hello world на C ++ с использованием iostream, двоичный файл которой (на x86, для конкретности) меньше 16 КБ и чья грязная память во время выполнения составляет менее одной страницы стека плюс одна страница данных. Я бы хотел, чтобы меня доказали, что он неправ, но, если это возможно, конечно, никто этого еще не сделал ... - person R.. GitHub STOP HELPING ICE; 04.03.2011
comment
Это полная реализация библиотеки C ++ или игрушечная реализация, чтобы доказать свою точку зрения? Если он полный, почему он не используется? - person R.. GitHub STOP HELPING ICE; 04.03.2011
comment
Моя причина не использовать его в том, что C ++ - глупый язык. В C ++ нет ничего такого, чего нельзя было бы сделать в C меньше, лучше и быстрее. В ЦП нет инструкций, которые оживают, потому что вы используете C ++. Во всяком случае, вы создадите обычный трудный для чтения беспорядок с ошибками, который представляет собой программа на C ++, вместо того, чтобы приближаться к металлу и ценить изящное искусство программирования. Встроенное программирование почти всегда требует ASM, и вы найдете здесь C ++ довольно недружелюбным. Просто мое мнение, основанное на 30-летнем опыте программирования встраиваемых систем ... - person ; 28.06.2013

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

person Zac Howland    schedule 28.02.2011
comment
Независимо от реализации, такие конструкции, как исключения, наследование и RTTI, требуют больше места для кода. Если есть сомнения в профиле. Правильность и надежность превыше всего. - person Thomas Matthews; 28.02.2011
comment
Пока вы используете только те функции, которые вам нужны. :-) - person Bo Persson; 28.02.2011
comment
Спасибо за этот список. Я не планировал использовать эти функции, но хорошо знать, чего следует избегать. - person Gregory Khrapunovich; 04.03.2011

C ++ хорош, если у вас достаточно ОЗУ и флэш-памяти во встроенной системе. Библиотека времени выполнения C ++ (libstdc ++) велика и поставляется в дополнение к стандартной библиотеке C (libc), даже если вы используете только C ++.

person GT.    schedule 28.02.2011
comment
Во встроенной системе в нее входят только необходимые библиотеки. Библиотеки, используемые для настольной версии, обычно намного больше и не имеют корреляции по размеру. Подделка в вопросах размера. См. Другой мой пост на SO. - person Thomas Matthews; 28.02.2011
comment
Это смелый ход, чтобы возразить против того факта, что libstdc ++ требует оперативной памяти и флэш-памяти ... - person GT.; 28.02.2011
comment
@ Томас: Я бы хотел, чтобы вы нашли способ сделать libstdc++ маленьким. uClibc++ существует не просто так; к сожалению, он довольно неполный. - person R.. GitHub STOP HELPING ICE; 01.03.2011

Вы можете использовать C ++, но будьте особенно осторожны.

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

Для скорости, профиля или случайной паузы часто. Очень легко сделать больше new и delete, чем вам действительно нужно, особенно с классами контейнеров, и будьте очень осторожны с такими вещами, как итераторы. Часто они делают вам ненужные услуги.

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

person Mike Dunlavey    schedule 28.02.2011

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

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

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

person Chris Stratton    schedule 04.03.2011

Я использую плату ARM9 для управления оборудованием, и я использую приложение C и C ++ на плате 500 МГц. Вам решать, использовать язык и как реализовать свою логику для реализации функциональности. Потому что я не обнаружил никаких проблем с запуском моего приложения в течение дня с контролем оборудования.

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

У меня нет проблем с запуском моего приложения Qt и программы C на плате ARM 9 с тактовой частотой 500 МГц.

person SamKan    schedule 20.02.2013