Предположим, что я работаю над научным кодом на C ++. В недавнем обсуждении с коллегой было высказано мнение, что шаблоны выражений могут быть очень плохой вещью, потенциально делая программное обеспечение компилируемым только на определенных версиях gcc. Предположительно, эта проблема затронула несколько научных кодов, о чем упоминалось в подзаголовках этой пародии на «Падение» . (Это единственные известные мне примеры, отсюда и ссылка.)
Однако другие люди утверждают, что шаблоны выражений полезны, потому что они могут повысить производительность, как в этой статье в SIAM Journal of Scientific Computing , избегая хранения промежуточных результатов во временных переменных.
Я не очень много знаю о метапрограммировании шаблонов в C ++, но я знаю, что это один из подходов, используемых в автоматическом дифференцировании и интервальной арифметике, и именно так я начал обсуждать шаблоны выражений. Учитывая как потенциальные преимущества в производительности, так и потенциальные недостатки в обслуживании (если это даже правильное слово), когда я должен использовать шаблоны выражений C ++ в вычислительной науке, а когда я должен их избегать?
источник
Ответы:
Моя проблема с шаблонами выражений заключается в том, что они являются очень утечкой абстракции. Вы тратите много времени на написание очень сложного кода, чтобы выполнить простую задачу с более приятным синтаксисом. Но если вы хотите изменить алгоритм, вам придется возиться с грязным кодом, и если вы ошибаетесь с типами или синтаксисом, вы получаете совершенно неразборчивые сообщения об ошибках. Если ваше приложение отлично отображается в библиотеке на основе шаблонов выражений, возможно, стоит подумать об этом, но если вы не уверены, я бы порекомендовал просто написать нормальный код. Конечно, высокоуровневый код менее красив, но вы можете просто делать то, что нужно. В качестве преимущества время компиляции и размеры двоичных файлов значительно сократятся, и вам не придется сталкиваться с огромными отклонениями в производительности из-за выбора компилятора и флага компиляции.
источник
Другие прокомментировали вопрос о том, насколько сложно писать программы ET, а также о сложности понимания сообщений об ошибках. Позвольте мне прокомментировать вопрос о компиляторах: это правда, что некоторое время назад одной из больших проблем был поиск компилятора, который достаточно совместим со стандартом C ++, чтобы все работало и работало переносимо. Как следствие, мы нашли много ошибок - у меня есть 2-300 отчетов об ошибках на мое имя, распределенных по gcc, Intel icc, IBM xlC и pgicc в Portland. Следовательно, скрипт конфигурации deal.II является хранилищем большого количества тестов ошибок компилятора, в основном в области шаблонов, объявлений друзей, пространств имен и т. Д.
Но оказывается, что производители компиляторов действительно сработались: сегодня gcc и icc сегодня проходят все наши тесты, и легко написать код, который переносим между ними. Я бы сказал, что PGI не сильно отстает, но у него есть ряд причуд, которые, похоже, не исчезнут за эти годы. С другой стороны, xlC - это совсем другая история - они исправляют ошибку каждые 6 месяцев, но, несмотря на то, что они годами регистрируют отчеты об ошибках, прогресс продвигается крайне медленно, и xlC никогда не была в состоянии успешно скомпилировать сделку. II.
Все это означает следующее: если вы придерживаетесь двух больших компиляторов, вы можете ожидать, что они просто работают сегодня. Поскольку сегодня большинство компьютеров и операционных систем обычно имеют хотя бы один из них, этого достаточно. Единственная платформа, где все сложнее, - это BlueGene, где системным компилятором обычно является xlC со всеми его ошибками.
источник
Я немного поэкспериментировал с ET, когда, как вы упомянули, компиляторы все еще боролись с ними. Я использовал блиц библиотеку для линейной алгебры в своем коде. Тогда проблема заключалась в получении хорошего компилятора, и, поскольку я не идеальный программист на C ++, интерпретировал сообщения об ошибках компилятора. Последний был просто неуправляемым. Компилятор в среднем генерирует около 1000 строк сообщений об ошибках. Я никак не мог быстро найти свою ошибку в программировании.
Вы можете найти более подробную информацию о цифрах веб-странице, (материалы двух семинаров ET).
Но я бы держался подальше от них ....
источник
Проблема уже начинается с термина «шаблоны выражений (ET)». Я не знаю, есть ли точное определение для этого. Но в обычном использовании он как-то сочетает «как вы кодируете выражения линейной алгебры» и «как это вычисляется». Например:
Вы кодируете векторную операцию
И это вычисляется циклом
На мой взгляд, это две разные вещи, и их необходимо отделить: (1) интерфейс и (2) одна возможная реализация. Я имею в виду, что это обычная практика в программировании. Конечно, (2) может быть хорошей реализацией по умолчанию, но в целом я хочу иметь возможность использовать специализированную, выделенную реализацию. Например, я хочу, чтобы такая функция, как
мне звонят, когда я кодирую (1). Возможно (3) просто использует цикл как в (2). Но в зависимости от размера вектора другие реализации могут быть более эффективными. В любом случае, некоторые специалисты по высокой производительности могут реализовать и настроить (3) как можно больше. Поэтому, если (1) не может быть сопоставлено с вызовом (3), тогда я скорее избегу синтаксического сахара (1) и сразу же вызову (3).
То, что я описываю, не является чем-то новым. Напротив, это идея BLAS / LPACK:
Если область действия BLAS недостаточна (например, она не обеспечивает функцию, подобную (3)), тогда можно расширить область действия BLAS. Таким образом, этот динозавр 60-х и 70-х годов с помощью своего инструмента каменного века реализует чистое и ортогональное разделение интерфейса и реализации. Забавно, что (большинство) числовых библиотек C ++ не достигают такого уровня качества программного обеспечения. Хотя сам язык программирования намного сложнее. Поэтому неудивительно, что BLAS / LAPACK все еще жив и активно развивается.
Так что, по моему мнению, инопланетяне сами по себе не являются злом. Но то, как они обычно используются в числовых библиотеках C ++, принесло им очень плохую репутацию в кругах научных компьютеров.
источник