о методах оптимизации и работы с памятью в C++

Mar 06, 2012 11:39


Хочу поделиться своим опытом по программированию и работе с памятью. Уже давно пришел к выводу, что для того, чтобы написать эффективный код (который будет быстро работать) нужно учитывать в первую очередь размещение объектов в памяти. Особенно это проявляется в методе программирования Data oriented design. Это метод, при котором в первую очередь ( Read more... )

Leave a comment

filoxsee March 21 2013, 08:00:20 UTC
Заказали мне на кафедре физики маленькую програмку моделирования частиц в определенной среде. Это не компилятор и не линковщик, но все эти методы были крайне необходимы. В несколько раз увеличивали скорость работы. Кстати программа использовала библиотеку CUDA, т.е. выполнялась не на CPU а на GPU, что еще в 1000 раз увеличивало скорость работы. То же относится к обработке изображения, где я использовал пиксельные шейдеры DirectX.

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

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

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

Reply

binf March 21 2013, 16:50:08 UTC
Не, я ни разу не сомневаюсь, что корректно написанное и целиком вручную оптимизированное нативное приложение без ошибок, использующее специальные методики управления памятью, будет быстрее, чем аналогичное в управляемой среде. Но кто сказал, что ваша програмка, будучи переписанной на функциональном яп, не заработала бы ещё быстрее? В 90% случаев сишно-сиплюсплюсный код менее производителен тупо из-за фрагментированности кучи.

Ну и прекрасно, пусть себе матрица хранится в контейнере с произвольным О(n) доступом. Не уловил суть примера. Или с++ позволяет создавать структуры данных, недоступные в Lisp?

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

Reply

filoxsee March 24 2013, 19:54:32 UTC
Смысл методов как раз не использовать фрагментированную кучу вообще.

Нет суть примера не в этом. Суть в том, что в зависимости от того, как хранить эту матрицу (по строкам или по столбцам, или еще как то, и соотносить это с алгоритмами, как эта матрица будет обрабатываться) будет зависеть скорость работы. Методы которые я описывал в статье относятся не к оптимизации C++. Они относятся к такому расположению данных в памяти, чтобы все быстрее работало (для других языков эти методы так же сгодятся). Я же не про С++ писал, а про Data oriented design.

Про 2.5 не понял. Хотите сказать, что рост производительности в 2 с половиной раза - это мало? Поиграйте в игру с 16 кадрами в секунду... А потом сравните ощущения с игрой в 40 кадров в секунду. Усилия на оптимизацию явно не будут напрасными!

Reply


Leave a comment

Up