Навчання оптимізації за допомогою складання [закрито]


21

Я студентка другого курсу технології комп’ютерних ігор. Нещодавно я закінчив свій перший прототип свого "власного" власного дорожника (який не використовує A *, а не геометричний підхід / розпізнавання візерунків. Pathfinder просто потребує знань про місцевість, на його думку, для прийняття рішень, тому що я хотів AI, який міг би насправді досліджувати, якщо місцевість уже відома, тоді вона пройде найкоротшим шляхом легко, тому що у дорожника є пам'ять вузлів).

У всякому разі, моє питання є більш загальним: як почати оптимізацію алгоритмів / циклів / for_each / тощо. використання збірки, хоча загальні поради вітаються. Я спеціально шукаю гарні книги, тому що справді важко знайти хороші книги на цю тему. Існує кілька невеликих статей, як ця , але все ще недостатньо знань для оптимізації алгоритму / гри ...

Я сподіваюся, що там є сучасна хороша книга, яку я просто не міг знайти ...


1
Це не відповідає безпосередньо на ваше запитання, але дослідницька (так звана адаптивна) A * була досліджена і має дуже хороші показники (це означає, що вам не потрібно буде оптимізувати її за допомогою ASM). Погляньте на D * Lite .
Джонатан Дікінсон

Відповіді:


21

Я буду тут проти зерна і скажу, що ніколи не зарано довідатися про оптимізації, особливо про оптимізацію складання та, що ще важливіше, налагодження в зборах. Я вірю, що ви отримаєте максимальну користь від цього, якщо будете студентом (адже тоді вам дуже мало втратити [тобто мудрий час / гроші]) і все, щоб отримати.

Якщо ви перебуваєте в галузі та вам не доручено займатися складанням, тоді не робіть цього. В іншому випадку, якщо ви студент або маєте час взагалі, я знайшов би час навчитися розбирати програми і бачити, чи зможу я придумати краще рішення, ніж компілятор. Якщо я не можу, хто дбає! Я щойно навчився писати, а також компілятор, і це ВЕЛИЧИЙ плюс, коли ви стикаєтеся з помилкою в коді випуску (без символів налагодження) і дивитесь на розбирання, тому що це єдине, що ви можете подивитися.

Відповідь

Це один з найкращих ресурсів, які я знайшов для вивчення оптимізацій.

http://www.agner.org/optimize/

Тираж

Якщо ви читаєте деякі статті головних розробників (наприклад, обґрунтування створення EASTL та ретельніша перевірка коду призведе до таких коментарів, як це було зроблено, тому що GCC жахливо викладати це, якщо заява, яка скаже вам, що більшість люди говорять, що ви довіряєте компілятору не завжди правильно, ОСОБЛИВО в розробці ігор), а потім ступивши в галузь, ви побачите, що оптимізація - це повсякденна річ, і знаючи, що означає вихід збірки, це великий плюс. Крім того, люди, здається, не усвідомлюють (особливо в стакверфілі), що ігри з профілюванням дуже важкі і не завжди точні.

Однак є застереження. Ви можете витратити час на оптимізацію чогось, а згодом зрозумієте, що був витрачений час. Але чого ти навчився? Ви навчилися не повторювати ту саму помилку за подібних обставин.

Що зараз займає ТА - це, на мою думку, релігійну позицію до твердження не оптимізуйте, доки ви не профіліруєтесь і не переживайте, компілятор знає краще за вас . Це перешкоджає навчанню. Я знаю експертів у цій галузі, яким платять дуже непогані гроші (і я маю на увазі ДУЖЕ хороші гроші), щоб спіткати в зборах, щоб оптимізувати гру та налагоджувати її, тому що компілятор поганий у цьому або просто не може вам допомогти, бо, ну, це не може (збої, пов’язані з графічним процесором, збої, коли дані, які задіяні, неможливо прочитати в налагоджувальному пристрої тощо)!

Що робити, якщо хтось, хто любить це робити, ще не повністю зрозумів цього, задає тут питання і відхиляється / вимикається багатьма відповідями, які компілятор знає краще за вас! і ніколи не стає одним із тих високооплачуваних програмістів?

Одна фінальна думка. Якщо ви почнете робити це рано, ви виявите, що незабаром ви почнете писати код, який у гіршому випадку не має жодних покращень продуктивності, оскільки компілятор оптимізував його так само або в кращому випадку, має деякі покращення продуктивності, тому що зараз компілятор може оптимізувати його . В будь-якому випадку це вже стало звичкою, і ви не повільніше пишете код таким чином, ніж те, що робили раніше. Кілька прикладів є (є ще багато):

  1. Попередній приріст, якщо ви дійсно не хочете після збільшення
  2. Написання циклів для контейнерів з використанням постійної змінної локального розміру, а не виклику size () на контейнері в циклі.

EDIT: Оновлення після 8 років у цій галузі. Вивчіть складання. Дізнайтеся, як працюють оптимізатори та збірка, яку вони генерують (CompilerExplorer - чудовий інструмент для цього). Я зіткнувся з незліченною кількістю збоїв у тестових збірках (оптимізованих складах для внутрішнього тестування), де ви не можете розраховувати на відладчик навіть із символами налагодження. Компілятор оптимізував занадто багато речей, і збірка є вашим єдиним джерелом цінної інформації, щоб знайти помилку на сміттєзвалищі. Кожна збірка займає 30-40 хвилин, якщо вам пощастить і спочатку в черзі збирання - тому ви не можете розраховувати на деякі традиційні методи, щоб виділити помилку. Мультиплеєр робить все гірше. Знання збірки та прочитання оптимізованої збірки просто зробить вас кращими та в кінцевому рахунку більш цінними для команди.


1
Хороший момент щодо оптимізації компіляторів. Вони чудово є, але вони далеко не ідеальні, і на відміну від того, що деякі люди вважають, зазвичай не важко знайти просту оптимізацію, яку компілятор не робив.
aaaaaaaaaaaa

3
Слід зазначити, що існує різниця між "навчанням читати складання" та "навчанням оптимізувати складання". Це не одне і те саме, і ваша відповідь не стосується використання збірки для здійснення оптимізації. Читання складання - корисна навичка, оскільки може допомогти у налагодженні та виявленні місць, де компілятор не робить щось правильно. Але це дуже відрізняється від фактичного використання збірки для написання оптимізованих процедур, що вимагає глибокого знання планування інструкцій для конкретного процесора. І це теж те, що ви не прикривали.
Нікол Болас

1
Крім того, "Я щойно навчився писати, як і компілятор" Ні, ви цього не зробили. Ви подивилися, як складено один конкретний режим для одного конкретного процесора. Навчання, як реалізувати оптимізовані процедури складання, вимагає більше, ніж дивитися на те, як компілятор склав одну процедуру. Ви повинні зрозуміти, чому компілятор обрав ці опкоди в тому порядку, щоб відтворити конкретний код C ++. А для цього потрібні інтимні знання процесора, планування інструкцій тощо. Для узагальнення цього потрібні багаторічний досвід; ви не отримаєте це, просто розшифрувавши пару процедур.
Нікол Болас

7
Отже, -1 для A: насправді не відповідає на запитання про те, як написати оптимізовані під збори процедури. B: неправильне представлення того, як легко навчитися перемагати компілятор під час написання програм, оптимізованих для складання. І С: заохочення програміста переглядати оптимізацію на рівні складання перед оптимізаціями на рівні алгоритму. Навіть високооплачувані "експерти в галузі" скажуть вам, що це ставить візок перед конем.
Нікол Болас

2
@Samaursa: Ніхто не сказав, що люди не повинні "розуміти розбирання та оптимізацію коду". Це не релігійна дискусія; справа простого факту. Люди витратили людину століттями, оптимізуючи певну рутину, лише щоб з'ясувати, що це нічого не означає для загальної роботи. Навчання оптимізації алгоритмів - дуже цінний набір навичок. Навчання читання складання - це напівцінний набір навичок. Навчитися писати складальні процедури - це набір навичок, який використовується дуже рідко. І в наші дні найкращі оптимізації виходять із кращого використання кешу, а не складання вручну.
Ніколь Болас

22

Перша порада, яку ви отримаєте, це така - не варто.

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

Виняток становитиме будь-який конкретний випадок, коли ви напевно визначили, що компілятор робить погану роботу з оптимізації, тож це друга порада. Тут немає загальних вказівок, вам потрібно знати власний код, знати, що він робить, вміти переходити до його розбирання та бути здатним точно визначити, що компілятор робить погану роботу.

Навіть у цьому випадку ви все одно можете не захотіти. Ви повинні бути впевнені, що поточні витрати на технічне обслуговування для вас не буде. Можливо, ви захочете повернутися до цього коду через 6 місяців і змінити його частину, або ви можете виявити надзвичайно тонкий помилку, який буде складніше виправити у версії мови складання. Навіть якщо ви думаєте, що ви відпрацювали всі помилки, як тільки ваша програма перейде до публічних помилок, ви ніколи навіть не думали, що це може статися, стануть для вас реальністю. Це досить відкриваюче око (і принижує досвід).

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


15

Зазвичай суцільна оптимізація не залежить від використання асамблеї або проведення мікрооптимізації з кодом на мовах вищого рівня. Якщо ви прочитаєте багато наукових робіт (як я це роблю - або намагаєтесь!), То побачите, що часто вдосконалення алгоритмів знаходяться на більш широкому концептуальному, "якісному" рівні, а не на більш "кількісному" рівень мікрооптимізації. Я підкреслюю, що підсилення на порядок швидше можна знайти, переглядаючи алгоритми з цієї точки зору, або векторизуючи / паралелюючи існуючі рішення.

Сказавши це, я нещодавно трапився з цим , що може бути хорошим маршрутом до вивчення x86 ASM спеціально для розробників ігор.


ДОБАВЛЕННЯ

Два джерела з моєї голови:

Крім того, читання наукових робіт є прекрасним способом прослідкувати розумні процеси розумних, оскільки вони оптимізують алгоритми для кращої роботи. Найчастіше виграші бачать:

  • Скорочення використання найдорожчих операцій (в першу чергу, div, SQRT, триггерів та умовних умов);
  • Покращення продуктивності кешу за рахунок використання більш ефективних структур даних, вирівнювання пам’яті та зменшення умов;
  • Зниження якості продукції у прийнятних районах для підвищення продуктивності;
  • Векторизація (SIMD);
  • Паралелізація (нарізка ниток, включає переключення завдань на GPU);
  • І звичайно (все рідше) ручне кодування. Спочатку огляньте збірки C / C ++, щоб побачити, де компілятор робить неоптимальний вибір, звичайно. Докладніше про це ви знайдете в старих статтях 80-90-х, IME.

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


Ви говорите про оптимізацію алгоритму, але не даєте про це ніякої інформації, якби ми дотримувались ваших порад і дивились на це, замість цього, чи могли б ви дати певний напрямок?
Скайт

Насправді я це згадую; вам потрібно вивчити алгоритми, розуміючи, що це робить комп'ютерні фахівці, щоб якісно підвищити продуктивність. Зануриться в це достатньо, і з часом ти починаєш мислити аналогічно. Поступові зусилля тут окупаються великим часом, на відміну від витрачених років (і я недавно бачив це на форумі ASM), освоюючи внески та виходи (наприклад). x86 архітектура. Полюйте на велику гру: навчіться зменшувати проблеми до самої основи, а потім вирішуйте, що зайве для оптимізації. Дивіться реф. Книги вище.
Інженер

@NickWiggill Яке звичне джерело дослідницьких робіт?
kizzx2

3

Я думаю, що це може бути занадто рано.

У будь-якому разі, важливо розуміти, що компілятор сам не виробляє повільніший код, ніж еквівалент збірки, ви не отримаєте жодної продуктивності, просто написавши той же код збірки, що і компілятор.

Для початку принаймні зосередьтеся на оптимізаціях без збірки. У Ігоря Островського є кілька хороших статей, що демонструють деякі основи: http://igoro.com/archive/fast-and-slow-if-statements-branch-prediction-in-modern-processors/

Зауважте, що непередбачення гілок та пропуски кешу - це те, з чим слід передусім оптимізувати, навіть якщо вам доведеться платити, виконуючи деякі додаткові арифметичні операції, як правило, варто цього уникати непередбачуваної гілки чи випадкового читання з занадто великої кількості пам'яті.

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


2

Ця книга надзвичайно гарна для текстової книги. Але це не спеціально орієнтоване на оптимізацію. Мова складання для процесорів x86, 6-е видання

Йдеться більше про навчання основ монтажу, використання MASM. Потім наприкінці книги з'ясовується, як скласти збірку за допомогою c ++ та інтегрувати її у більші програми.

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

Мені подобається ця книга, тому що Ірвайн вчить, як користуватися інструментами, необхідними для написання програм масажів. Він спеціально розглядає, як використовувати IDE (Visual Studio C ++) та відладчик. У кожному розділі є кілька відео, присвячених вирішенню проблем. Частина цієї інформації вільно розміщена на переліченому веб-сайті.


1
"має сенс вивчити основи складання, перш ніж навчитися оптимізувати програми за допомогою неї" - хороша порада.
Максим Мінімус
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.