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


16

За даними сторінки Вікіпедії щодо статичного єдиного призначення (SSA) , SSA використовується великими і відомими проектами, такими як LLVM, GCC, MSVC, Mono, Dalvik, SpiderMonkey і V8, а сторінка для проектів, що використовують стиль продовження проходження (CPS) трохи бракує для порівняння.

Я маю таке уявлення, що CPS віддають перевагу компіляторам та інтерпретаторам, які реалізують в основному функціональні мови - зокрема, Haskell і Scheme, здається, мають сильний нахил до стилю CPS через обмеження мутації або необхідність першокласної підтримки продовження (я б здогадався що Smalltalk, можливо, також знадобиться цього). Основна література, з якою я стикався, що використовує CPS, здається, є ті, які в першу чергу працюють над Схемою або в деякому відношенні пов'язані зі Схемою.

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


3
IIRC, традиційні оптимізації для імперативних мов, розроблені в дні традиційного аналізу потоків даних, передаються в форму SSA легше, ніж це стосується CPS. Зокрема, ланцюги use-def та def-use можуть бути "зчитані" представлення SSA безпосередньо. Інертність розраховує на щось
Псевдонім

Відповіді:


9

Я думаю, що багато реалізаторів компіляторів для типових імперативних мов просто не були знайомі з методами компіляції на основі CPS та CPS. У спільноті функціонального програмування як компіляція на базі CPS, так і CPS є дуже відомими методами - остання з роботи Гая Стіла. Тим не менш, навіть у спільноті FP більшість компіляторів не використовують методи компіляції на основі CPS, якщо мова не підтримує операторів управління, як call/cc. Використовується щось подібне до адміністративної нормальної форми (ANF) (іноді її також називають монадійною нормальною формою, яка тісно пов'язана з причин, які стануть зрозумілими), яка має ще більш жорсткі стосунки до SSA, ніж CPS .

Якщо я добре пам’ятаю, адміністративна нормальна форма отримала свою назву від того, що компіляція на основі CPS може призвести до бета-перенастроювання проміжного коду, який не відповідав нічого у вихідному коді. Їх називали "адміністративними переробленнями". Вони можуть скоротитися під час компіляції, але було проведено велику кількість досліджень щодо виконання перетворення CPS, яке б виводило код без адміністративних перестановок. Мета цього полягала в тому, щоб випускати продукцію в нормальній формі, де всі "адміністративні" зміни були зменшені, і це було походженням адміністративної нормальної форми. Зрозуміло, що не було багато користі для того, щоб сприймати це як (n оптимізацію а) двоетапного процесу: перетворення CPS, зменшення адміністративних оновлень. Зокрема, нормальна адміністративна форма виглядає скоріше як монадійський стиль, як це практикується (вручну), особливо в Хаскеллі. Перетворення CPS можна розуміти як перетворення в монадійний стиль, коли ви просто використовуєте монаду CPS (тому дійсно існує багато способів "перетворити" в монадійний стиль, що відповідає різним замовленням на оцінку). Взагалі, однак, ви можете використовувати зовсім іншу монаду, і тому перетворення в монадійський стиль і, таким чином, адміністративно нормальна форма насправді не пов'язане зокрема з CPS.

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

Проблема з CPS пов'язана з однією з головних її переваг. Трансформація CPS дозволяє вам реалізувати такі оператори керування call/cc, але це означає, що кожен не локальний виклик функції в проміжному коді CPS повинен розглядатися як потенційно виконуючий керуючі ефекти. Якщо у вашій мові є оператори керування, то це саме так, як і повинно бути (хоча навіть тоді більшість функцій, ймовірно, не виконують жодних шенагіганів управління). Якщо у вашій мові не входять оператори управління, то існують глобальні інваріанти щодо використання продовжень, які не очевидні локально. Це означає, що є оптимізація, яка не є голосною для виконання загального коду CPS, що було б здорово виконувати на цьому особливо добре сприйнятому використанні CPS. Один із способів цього проявляється взміна точності даних та аналіз потоків контролю . (Трансформація CPS в деяких випадках допомагає, шкодить іншим, хоча способи, які вона допомагає, здебільшого пояснюються дублюванням, а не самим аспектом CPS.) 1 Ви, звичайно, можете додати правила та коригувати аналізи, щоб компенсувати це (тобто використовувати глобальні інваріанти), але потім ви частково перемогли одну з головних переваг компіляції на основі CPS, яка полягає в тому, що багато (здавалося б) спеціальні оптимізації перетворюються на особливі випадки оптимізації загального призначення (зокрема бета-скорочення ).

Зрештою, якщо у вашій мові немає операторів управління, зазвичай не так багато причин використовувати схему компіляції на основі CPS. Як тільки ви компенсуєте проблеми, про які я згадував вище, ви зазвичай усунули переваги компіляції на основі CPS і створили щось еквівалентне тому, що не використовуєте CPS. У цей момент CPS просто робить проміжний код із закругленим виглядом для не дуже великої вигоди. Аргумент для компіляції на основі CPS з 2007 року вирішує деякі з цих питань та представляє деякі інші переваги, використовуючи іншу форму перетворення CPS. Речі, які приносить папір, частково охоплені документом (2017), про який я згадував раніше.

1 Чи не робить еквівалентність між SSA та CPS це більш-менш неможливим? Ні. Одне з перших речей, в якому вводиться ця еквівалентність, полягає в тому, що еквівалентність не працює для довільного коду CPS, але вона працює для виведення перетворення CPS (який вони визначають) для мови без операторів управління.


2
З часу первинної відповіді минуло деякий час, але я відчуваю себе досить добре, щоб нарешті прийняти відповідь, тому що я розумію більше 10% ...
CinchBlue

2

Я не експерт-компілятор, тому прийміть те, що я кажу, із зерном солі, сподіваюся, що справжній експерт-компілятор задзвенить. Мені сказали:

  • CPSed-код має тенденцію стрибкувати не локально, що знищує кеш-локальність, отже, і продуктивність.
  • CPS вимагає більш дорогого збирання сміття, ніж звичайна компіляція, яка, як правило, може зберігати багато матеріалів на стеку (що швидше виділяти та розбирати).

Обидва мають змову робити код, складений CPS-трансформацією порівняно повільно.


3
Я думаю, що ви змішуєте CPS-трансформований вихідний код (або перетворення на джерело-джерело) з використанням CPS як проміжної мови. Якщо припустити, що мова вводу не підтримує ефекти керування, як call/cc, наприклад, продовження буде використовуватися з дисципліною стека - не потрібно буде збирати сміття, і продовження буде відповідати більш-менш краям потоку управління графік, тому зайвих стрибків не буде. Не потрібно реалізовувати продовження, використовуючи деякі загальні цілі реалізації функцій вищого порядку.
Дерек Елкінс виїхав SE

@DerekElkins Мені було незрозуміло, про що питають ОП.
Мартін Бергер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.