Тестирование производительности для сложных программ - PullRequest
1 голос
/ 07 мая 2009

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

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

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

Редактировать: Чтобы указать немного больше. Я использую C #, и все мои алгоритмы вращаются вокруг вычисления и решения проблем типа ограничений для выражений (с использованием деревьев выражений). Под выражениями я подразумеваю такие вещи, как x ^ 2 + 4 или что-то еще, подобное тому, которое будет проанализировано в дереве выражений. Все мои алгоритмы создают и управляют этими деревьями, чтобы попытаться найти лучшие приближения. Но я хотел поставить вопрос в общем виде на случай, если он кому-нибудь поможет.

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

Ответы [ 5 ]

3 голосов
/ 08 мая 2009

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

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

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

Кроме того, нужно подумать о том, как лучше всего реструктурировать ваш код, и это зависит от проблемы. Может случиться так, что вы только что получили цикл, который компилятор не очень хорошо оптимизирует, и вы можете встроить или переместить элементы в / из цикла, чтобы помочь компилятору. Или, если вы работаете так быстро, как можете, используя базовые арифметические операции, вы можете попытаться использовать векторные инструкции (SSE и т. Д.). Если ваш код работает параллельно, у вас могут возникнуть проблемы с балансировкой нагрузки, и вам может понадобиться реструктурируйте свой код так, чтобы данные лучше распределялись по ядрам.

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

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

3 голосов
/ 07 мая 2009

Это почти такой же процесс, как и любая другая оптимизация: профиль, эксперимент, тест, повтор.

Сначала вы должны выяснить, какие разделы вашего кода занимают время. Затем попробуйте разные методы, чтобы ускорить их (лучше использовать методы, основанные на достоинствах, чем случайные попытки). Тест, чтобы узнать, действительно ли вы их ускорили. Если вы это сделали, замените старый метод новым. Профиль снова.

2 голосов
/ 08 мая 2009

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

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

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

Старайтесь избегать ненужного выделения и удаления памяти. Вот где имеет смысл отказаться от чисто ОО-подхода.

1 голос
/ 08 мая 2009

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

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

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

initialize:
float y = 0; // y coordinate
float yi = 0; // incremental variable

loop:
y += yi;
yi += 0.001;

if (y > 10)
  yi = -yi;

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

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

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

y += yi * 0.01;

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

0 голосов
/ 08 мая 2009

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

Стандартными узкими местами в численных алгоритмах являются память использование (вы получаете доступ к матрицам в том порядке, в котором элементы хранятся в памяти); накладные расходы на связь и т. д. может немного отличаться от других нечисловых программ.

Кроме того, многие другие факторы, такие как предварительная подготовка и т. Д. может привести к резкой разнице в поведении ОДНОГО ЖЕ алгоритма по той же проблеме. Удостовериться Вы определяете оптимальные параметры для ваших реализаций.

Что касается сравнения разных алгоритмов, рекомендую чтение газеты

«Программное обеспечение для оптимизации бенчмаркинга с профилями производительности» Хорхе Море и Элизабет Д. Долан, Математическое программирование 91 (2002), 201-213.

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

Удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...