2009-11-03 2 views
4

У меня есть очень большая программа, которую я собирал под визуальной студией (v6 затем перенесен на 2008). Мне нужно, чтобы исполняемый файл выполнялся как можно быстрее. Программа тратит большую часть времени на обработку целых чисел различных размеров и делает очень мало ввода-вывода.Выполнение максимально возможного исполняемого файла

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

Итак, мой вопрос: существуют ли другие параметры компилятора/компоновщика, которые я должен использовать, чтобы ускорить выполнение программы, не контролируемую на странице «Оптимизация» диалогового окна «Свойства».

EDIT: Я уже широко использую профилировщики.

+0

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

+0

Я действительно попробовал компилятор Intel около года назад, и он выпустил код, который был примерно такой же, как у Microsoft ... хотя, возможно, я не знал, как настроить все параметры максимальной скорости. Я бы попробовал еще раз, если бы услышал, что многие сообщения об этом были значительно быстрее, или кто-то сказал: «Вы попробовали его с флагом X, который заставляет его работать быстрее» или некоторые из них. – Mick

+0

Нужно ли быстрее работать на конкретной платформе? Или как можно быстрее на нескольких платформах (при условии, что всегда есть компромиссы)? – Kylotan

ответ

5

1) Уменьшите наложение с помощью __restrict.

2) Помогите компилятору устранить исключение общего кода или уничтожить код с помощью __pure.

3) Введение в SSE/SIMD можно найти here и here. Интернет не совсем переполнен статьями по теме, но этого достаточно. Для справочного списка встроенных функций вы можете искать MSDN для 'compir intrinsics'.

4) Для «макропараллельности» вы можете попробовать OpenMP. Это стандарт компилятора для простой распараллеливания задач - по сути, вы говорите компилятору, используя несколько #pragmas, что некоторые разделы кода являются реентерабельными, а компилятор автоматически создает потоки для вас.

5) Я второй вопрос interjay о том, что PGO может быть очень полезным. И в отличие от # 3 и # 4, это почти без усилий, чтобы добавить в

12

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

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

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

+1

+3 (если возможно) 100% согласны с каждой точкой. Вы избили меня, чтобы прокомментировать его размер. Многие люди не думают об этом при оптимизации. – Marcin

+1

+1 - Общая рекомендация в настоящее время из-за высокой дисперсии времени доступа к памяти - это глобальная оптимизация по размеру и оптимизация для скорости только настоящих узких мест. Цикл, чтобы долго вписываться в кеш-код, может повредить вам в 10 раз, узкое место, оптимизированное для размера, а не скорость, повредит вам около 1.alittle. – peterchen

+0

Не будет устанавливать равный приоритет для скорости и размера хорошая идея? – henle

3

Забудьте микро-оптимизацию, такую ​​как то, что вы описываете. Запустите приложение через профилировщик (есть один, включенный в Visual Studio, по крайней мере в некоторых изданиях). Профайлер расскажет вам, где ваше приложение тратит свое время.

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

8

Profile-guided optimization может привести к большому ускорению. Мое приложение работает на 30% быстрее с помощью сборки PGO, чем обычная оптимизированная сборка. В принципе, вы запускаете свое приложение один раз и позволяете Visual Studio профилировать его, а затем он снова создается с оптимизацией на основе собранных данных.

1

Я согласен с тем, что все говорили о профилировании. Однако вы указываете «целые числа разных размеров». Если вы делаете много арифметики с несогласованными целыми числами, много времени может быть потрачено впустую при изменении размеров, например, шортах на int, когда выражения оцениваются.

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

1

У вас есть три пути ускорения приложения:

  1. Лучше алгоритма - вы не указали алгоритм или типов данных (это есть верхний предел размера целого числа?) Или то, что вывод, который вы хотеть.

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

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

+0

Я думал, что компилятор уже использовал инструкции SIMD, где это возможно, когда при максимальной оптимизации. Нет? – Mick

+0

Всё зависит. Простые вещи, такие как суммирующие массивы целых чисел, вероятно, оптимизированы в SIMD, если у вас есть параметры компилятора.Если это более сложный алгоритм, вероятность, вероятно, уменьшается. Единственный способ узнать это - посмотреть на код, который создал компилятор. – Skizz

+0

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

5

Вы спрашиваете, какие опции компилятора могут помочь вам ускорить вашу программу, но вот некоторые общие советы по оптимизации:.

1) Убедитесь, что ваши алгоритмы подходят для работы. Никакое количество возиться с параметрами компилятора не поможет вам, если вы напишете алгоритм O (квадрат квадрата).

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

3) Поймите платформу, над которой вы работаете. Понимать, как работают кэши для этого ЦП, и писать код, который специально использует преимущества аппаратного обеспечения. Убедитесь, что вы не следуете указателям везде, чтобы получить доступ к данным, которые будут разбивать кеш. Поймите доступные SIMD-операции и используйте встроенные средства, а не записывайте сборку. Только писать сборку, если компилятор определенно не генерирует правильный код (т. Е. Плохо записывает в нераскрытую память). Убедитесь, что вы используете __restrict для указателей, которые не будут псевдонимом. Некоторые платформы предпочитают передавать векторные переменные по значению, а не по ссылке, поскольку они могут сидеть в регистрах - я мог бы продолжить это, но этого должно быть достаточно, чтобы указать вам в правильном направлении!

Надеется, что это помогает,

-Tom

2

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

Также вы можете бросить оборудование по этой проблеме. Возможно, на вашем ПК уже есть необходимое оборудование, в основном неиспользованное: графический процессор! Одним из способов повышения производительности некоторых типов вычислительно дорогостоящей обработки является ее выполнение на графическом процессоре. Это аппаратная спецификация, но NVIDIA предоставляет API для этого: CUDA. Использование GPU, скорее всего, даст вам гораздо большее преимущество, чем использование процессора.

2

Проверьте, какой режим/точность вы используете. Каждый из них генерирует совершенно другой код, и вам нужно выбирать, исходя из того, какая точность требуется в вашем приложении.Наш код нуждается в точности (геометрия, графический код), но мы по-прежнему используем/fp: fast (C/C++ -> Опции генерации кода).

Также убедитесь, что у вас есть/arch: SSE2, предполагая, что ваше развертывание охватывает процессоры, поддерживающие SSE2. Это приведет к довольно большой разнице в производительности, поскольку компилятор будет использовать очень мало циклов. Подробности в блоге хорошо освещены SomeAssemblyRequired

Поскольку вы уже профилируете, я бы предложил цикл разворачивания, если этого не происходит. Я видел, что VS2008 не делал этого чаще (шаблоны, ссылки и т. Д.)

Используйте __forceinline в горячих точках, если применимо.

Измените горячие точки вашего кода на использование SSE2 и т. Д., Так как ваше приложение, похоже, интенсивно вычисляется.

0

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

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

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

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

This is an example of what I'm talking about.

Смежные вопросы