Pull to refresh

Эффективность C++ на современных ПК

Reading time 2 min
Views 3.5K
C++ *
В виду ограничения на размер, публикую заметку в виде статьи, а не как ссылку с аннотацией.

Со времён, когда проектировался С++, относительная (к скорости оперативной памяти) скорость процессора выросла в 400 раз. Плюс к тому, у процессора появились большие кэши и предсказание ветвлений в коде. Всё это вместе самым серьёзным образом сказывается на эффективности С++ на современных платформах. Ниже даю аннотацию и пару ссылок, где предлагается использовать эти факты для повышения эффективности кода.
Читать дальше →
Total votes 59: ↑48 and ↓11 +37
Comments 49

Сетевой код для бедных

Reading time 11 min
Views 36K
Game development *Network technologies *
Translation

Чем больше узнаёшь в своей области знания, тем чётче понимаешь, что никто не может знать всего.

По какой-то причине (за что, господи, за что?) моей областью стала разработка игр. Каждый, кто работает в этой сфере, скажет вам: никогда не добавляй сетевой многопользовательский режим в уже готовую игру, никогда, пьяный ты клоун.

Как бы то ни было, я именно это и сделал, и ненавижу себя за это. На удивление, вышло замечательно. Никто из нас не знает всего.

Проблема №1: ресурсы


Первый вопрос, который у меня возник: как сказать клиенту, что для рендеринга объекта нужно использовать такой-то меш?

Сериализировать весь меш? Не стоит, у клиента он уже есть на диске.

Передавать имя файла? Не-а, малоэффективно и небезопасно.

Ну ладно, может быть, просто строковый идентификатор?

К счастью, прежде чем у меня появилось время на реализацию собственных бредовых идей, я посмотрел доклад Майка Эктона, в котором он говорил об опасностях «ленивого принятия решений». Смысл в следующем: строки позволяют разработчикам лениво игнорировать принятие решений до момента создания работающего приложения, когда исправлять ошибки уже поздно.
Total votes 49: ↑47 and ↓2 +45
Comments 20

Data-Oriented Design (или почему, используя ООП, вы, возможно, стреляете себе в ногу)

Reading time 10 min
Views 30K
Programming *Client optimization *ООP *
Translation
image

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

Такое развитие событий довольно точно описывает почти каждую игру, в разработке которой я участвовал на протяжении последних десяти лет. Причины заключаются не в языках программирования и не в инструментах разработки, и даже не в отсутствии дисциплины. По моему опыту, в большой степени в этом стоит винить объектно-ориентированное программирование (ООП) и окружающую его культуру. ООП может не помогать, а мешать вашим проектам!
Читать дальше →
Total votes 34: ↑30 and ↓4 +26
Comments 18

Как я на спор развернул двусвязный список за O(1)

Reading time 7 min
Views 67K
Pixonic corporate blog Abnormal programming *Entertaining tasks Programming *

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

Вернее, не так.

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

  • Почему по умолчанию все решают задачу именно так?
  • Можно ли сделать лучше?
Читать дальше →
Total votes 192: ↑154 and ↓38 +116
Comments 125

«Компилятор всё оптимизирует»? Ну уж нет

Reading time 11 min
Views 11K
Perfect code *Client optimization *Compilers *
Translation
Многие программисты считают, что компиляторы — это волшебные «чёрные ящики», на вход в которые можно подать хаотичный код, а на выходе получить красивый оптимизированный двоичный файл. Доморощенные философы часто начинают рассуждать о том, какие фишки языка или флаги компилятора следует использовать, чтобы раскрыть всю мощь магии компилятора. Если вы когда-нибудь видели кодовую базу GCC, то и в самом деле могли поверить, что он выполняет какие-то волшебные оптимизации, пришедшие к нам из иных миров.

Тем не менее, если вы проанализируете результаты работы компиляторов, то узнаете, что они не очень-то хорошо справляются с оптимизацией вашего кода. Не потому, что пишущие их люди не знают, как генерировать эффективные команды, а просто потому, что компиляторы способны принимать решения только в очень малой части пространства задач. [В своём докладе Data Oriented Design (2014 год) Майк Эктон сообщил, что в проанализированном фрагменте кода компилятор теоретически может оптимизировать лишь 10% задачи, а 90% он оптимизировать не имеет никакой возможности. Если бы вам интересно было узнать больше о памяти, то стоит прочитать статью What every programmer should know about memory. Если вам любопытно, какое количество тактов тратят конкретные команды процессора, то изучите таблицы команд процессоров]

Чтобы понять, почему волшебные оптимизации компилятора не ускорят ваше ПО, нужно вернуться назад во времени, к той эпохе, когда по Земле ещё бродили динозавры, а процессоры были чрезвычайно медленными. На графике ниже показаны относительные производительности процессоров и памяти в разные годы (1980-2010 гг.). [Информация взята из статьи Pitfalls of object oriented programming Тони Альбрехта (2009 год), слайд 17. Также можно посмотреть его видео
(2017 год) на ту же тему.]

Читать дальше →
Total votes 37: ↑34 and ↓3 +31
Comments 31

Полиморфные структуры данных и производительность

Reading time 5 min
Views 5.3K
High performance *Abnormal programming *Open source *Programming *C++ *

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

Читать далее
Total votes 13: ↑12 and ↓1 +11
Comments 45