Date: 2015-01-30 02:00 pm (UTC)
Приведенный пример почти из реальной жизни, только он характерен не для C, а для C++. Там за счет шаблонов очень часто порождается лишний код - временные объекты и ссылки, бессмысленные копирования и т.д. Раньше из-за этого C++ был медленным, и это породило миф, что C++ медленнее C. Это давно уже не так - современные компиляторы вырезают такой код так же эффективно, как и порождают, особенно если используется STL-библиотека с поддержкой C++11 (конкретно - move constructor). У меня есть примеры кода, которые из 100-200 строк сворачиваются в 1-2 машинных команды. (Зачем так писать? Затем, что это нужно для гибкости - изменение всего одной строчки приводит к генерации совсем другого кода. Это способ решения задач в условиях почти полного отсутствия техзадания - "сделаем лего, а потом из лего быстренько соберем решение").

Современный Си оптимизирует вычислительное программирование не хуже, чем Фортран. Раньше была проблема, что написание указателя автоматически означало, что переменная честно ляжет в память и будет честно взят указатель. Сейчас не так, сейчас компилятор лишние указатели подавляет. И даже лишние if умеет на арифметику заменять. Поэтому код на си и код на фортране скорее всего скомпилируются просто в идентичный машинный код, даже если их пишет человек с "сопутствующим навыком". Главное, чтобы этот человек не пытался "умничать" и использовать всякие "оптимизации", о которых прочитал в учебнике по Си 1989 года издания. Вот этим реально можно оптимизатор раком поставить. Например, написать malloc() вместо простого int x[100], побоявшись, что 100 элементов - это много. (Люди добрые, да современный стек массив из миллиона элементов скушает и не подавится!) Вообще, чем проще и примитивнее написана программа, тем легче оптимизатору ее понимать.

Гадости из стандарта фортрана 2003 - это, например, параграф 6.2.2.2 "Array element order", который зачем-то регламентирует расположение элементов массива в памяти. Это имеет смысл только при грязном касте через передачу в процедуру не того типа или через EQUIVALENCE. Второе имело смысл только во времена БЭСМ, первое использовалось для самодельных аллокаторов в Fortran-77 и утратило смысл в Fortran-90. Но фактически этот параграф запрещает компилятору раскладывать короткие массивы по регистрам. А значит, в программе, в которой много трехмерных векторов и скалярных произведений, компилятор, не нарушая стандарта, не сможет распихать эти массивы по регистрам и использовать инструкции SSE. Вместо того, чтобы делать скалярное произведение одной инструкцией, он сделает честный цикл из перемножений и сложений. Чтобы уж совсем забить гвоздь в крышку гроба SSE, есть еще вот такой параграф: 16.4.3.1 (7) A nonpointer array occupies a sequence of contiguous storage sequences, one for each array element, in array element order. Ну а весь параграф 16.4.3.3 "Association of scalar data objects" - это вообще гадость, не имеющая аналогов ни в каких современных языках программирования. Как раз та штука, с которой современная теория компиляторов вообще справляться не умеет.

If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting
Page generated Feb. 9th, 2026 07:10 am
Powered by Dreamwidth Studios