Закрити оголошення

Майк Еш присвятив у своєму блозі практичні наслідки переходу на 64-розрядну архітектуру в iPhone 5S. Ця стаття спирається на його висновки.

Причина цього тексту в основному через велику кількість дезінформації, яка поширюється про те, що новий iPhone 5s із 64-розрядним процесором ARM насправді означає для користувачів і ринку. Тут ми спробуємо надати об’єктивну інформацію про продуктивність, можливості та наслідки цього переходу для розробників.

"64 біт"

Існують дві частини процесора, на які може посилатися позначка «X-bit» - ширина цілочисельних регістрів і ширина покажчиків. На щастя, на більшості сучасних процесорів ці ширини однакові, тому у випадку з A7 це означає 64-розрядні цілі регістри та 64-розрядні покажчики.

Однак не менш важливо вказати, що «64-розрядний» НЕ означає: Розмір фізичної адреси RAM. Кількість бітів для зв’язку з оперативною пам’яттю (тобто обсяг оперативної пам’яті, який може підтримувати пристрій) не пов’язана з кількістю бітів ЦП. Процесори ARM мають 26- і 40-бітні адреси, і їх можна змінювати незалежно від решти системи.

  • Розмір шини даних. Обсяг даних, отриманих з оперативної пам'яті або буферної пам'яті, також не залежить від цього фактора. Індивідуальні інструкції процесора можуть вимагати різні обсяги даних, але вони або надсилаються частинами, або надходять із пам’яті більше, ніж потрібно. Це залежить від розміру кванта даних. iPhone 5 вже отримує дані з пам'яті в 64-бітних квантах (і має 32-бітний процесор), і ми можемо зустріти розміри до 192 бітів.
  • Усе, що стосується числа з плаваючою комою. Розмір таких регістрів (FPU) також не залежить від внутрішньої роботи процесора. ARM використовує 64-розрядний FPU ще до ARM64 (64-розрядний процесор ARM).

Загальні переваги та недоліки

Якщо порівняти однакові 32- і 64-бітні архітектури, то вони, як правило, не такі вже й різні. Це одна з причин загального збентеження громадськості, яка шукає причину, чому Apple також переходить на 64-розрядні мобільні пристрої. Однак все залежить від конкретних параметрів процесора A7 (ARM64) і того, як Apple його використовує, а не лише від того, що процесор має 64-розрядну архітектуру.

Однак якщо ми все ж подивимося на відмінності між цими двома архітектурами, то знайдемо кілька відмінностей. Очевидно, що 64-розрядні цілі регістри можуть обробляти 64-розрядні цілі числа більш ефективно. Навіть раніше з ними можна було працювати на 32-розрядних процесорах, але це зазвичай означало поділ їх на 32-розрядні частини, що спричиняло повільніші обчислення. Отже, 64-розрядний процесор, як правило, може обчислювати 64-розрядні типи так само швидко, як і 32-розрядні. Це означає, що програми, які зазвичай використовують 64-розрядні типи, можуть працювати набагато швидше на 64-розрядному процесорі.

Хоча 64-розрядна версія не впливає на загальний обсяг оперативної пам’яті, яку може використовувати процесор, вона може полегшити роботу з великими фрагментами оперативної пам’яті в одній програмі. Будь-яка програма, що працює на 32-розрядному процесорі, має лише близько 4 ГБ адресного простору. Беручи до уваги, що операційна система та стандартні бібліотеки займають дещо, це залишає програмі десь 1-3 ГБ для використання додатком. Однак якщо 32-розрядна система має більше 4 ГБ оперативної пам’яті, використання цієї пам’яті дещо складніше. Ми повинні вдатися до того, щоб змусити операційну систему зіставляти ці більші шматки пам’яті для нашої програми (віртуалізація пам’яті), або ми можемо розділити програму на кілька процесів (де кожен процес теоретично має 4 ГБ пам’яті, доступної для прямої адресації).

Однак ці «зломи» настільки складні та повільні, що їх використовує мінімум програм. На практиці на 32-розрядному процесорі кожна програма використовуватиме лише свої 1–3 ГБ пам’яті, а більше доступної оперативної пам’яті можна використовувати для запуску кількох програм одночасно або використовувати цю пам’ять як буфер (кешування). Це практичне використання, але ми хотіли б, щоб будь-яка програма могла легко використовувати фрагменти пам’яті розміром понад 4 ГБ.

Тепер ми підійшли до частого (насправді невірного) твердження, що без більш ніж 4 ГБ пам’яті 64-бітна архітектура марна. Більший адресний простір корисний навіть у системі з меншим обсягом пам’яті. Файли з відображенням пам’яті є зручним інструментом, де частина вмісту файлу логічно пов’язана з пам’яттю процесу без необхідності завантажувати весь файл у пам’ять. Таким чином, система може, наприклад, поступово обробляти великі файли, які у багато разів перевищують обсяг оперативної пам'яті. У 32-розрядній системі такі великі файли не можуть бути надійно відображені в пам’яті, тоді як у 64-розрядній системі це просто шматок пирога завдяки набагато більшому адресному простору.

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

ARM64

A7, 64-розрядний процесор нового iPhone 5s, це не просто звичайний процесор ARM із ширшими регістрами. ARM64 містить значні покращення порівняно зі старішою 32-розрядною версією.

Процесор Apple A7.

реєстру

ARM64 містить вдвічі більше цілих регістрів, ніж 32-розрядний ARM (будьте обережні, щоб не переплутати кількість і ширину регістрів — ми говорили про ширину в розділі «64-розрядні»). Отже, ARM64 має вдвічі ширші регістри та вдвічі більше реєстри). 32-розрядна ARM має 16 цілих регістрів: один програмний лічильник (PC - містить номер поточної інструкції), покажчик стека (покажчик на функцію, що виконується), регістр зв'язку (покажчик на повернення після закінчення функції), а решта 13 призначені для використання програмою. Однак ARM64 має 32 цілочисельних регістри, включаючи один нульовий регістр, регістр зв’язку, покажчик кадру (схожий на покажчик стека) і один, зарезервований на майбутнє. Це залишає нам 28 регістрів для використання програмами, що більш ніж удвічі перевищує 32-розрядний ARM. У той же час ARM64 подвоїв кількість регістрів чисел з плаваючою комою (FPU) з 16 до 32 128-розрядних регістрів.

Але чому кількість реєстрів така важлива? Пам'ять, як правило, повільніше, ніж обчислення ЦП, і читання/запис може тривати дуже довго. Це змусило б швидкий процесор чекати пам’яті, і ми досягли б природного обмеження швидкості системи. Процесори намагаються приховати цей недолік за допомогою шарів буферів, але навіть найшвидший (L1) все одно повільніший за обчислення процесора. Однак регістри - це комірки пам'яті безпосередньо в процесорі, і їх читання/запис відбувається досить швидко, щоб не сповільнювати процесор. Кількість регістрів практично означає обсяг найшвидшої пам'яті для обчислень процесора, що сильно впливає на швидкість роботи всієї системи.

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

Набір інструкцій

ARM64 також вносить значні зміни в набір інструкцій. Набір інструкцій — це набір атомарних операцій, які може виконувати процесор (наприклад, 'ADD register1 register2' додає числа в двох регістрах). Функції, доступні для окремих мов, складаються з цих інструкцій. Більш складні функції повинні виконувати більше інструкцій, тому вони можуть працювати повільніше.

Нові в ARM64 інструкції для шифрування AES, хеш-функцій SHA-1 і SHA-256. Тож замість складної реалізації ця інструкція буде викликатися лише мовою, що значно пришвидшить обчислення таких функцій і, сподіваємося, додасть безпеки в програмах. наприклад новий Touch ID також використовує ці інструкції для шифрування, що забезпечує реальну швидкість і безпеку (теоретично, зловмиснику доведеться модифікувати сам процесор, щоб отримати доступ до даних – що, м’яко кажучи, непрактично, враховуючи його мініатюрний розмір).

Сумісність з 32 біт

Важливо відзначити, що A7 може повністю працювати в 32-розрядному режимі без необхідності емуляції. Це означає, що новий iPhone 5s може запускати програми, скомпільовані на 32-бітній ARM, без будь-яких уповільнень. Однак тоді він не може використовувати нові функції ARM64, тому завжди варто зробити спеціальну збірку лише для A7, яка повинна працювати набагато швидше.

Зміни часу виконання

Середовище виконання — це код, який додає функції до мови програмування, які вона може використовувати під час роботи програми до завершення перекладу. Оскільки Apple не потребує підтримки сумісності додатків (що 64-розрядний двійковий файл працює на 32-розрядному), вони можуть дозволити собі зробити ще кілька покращень у мові Objective-C.

Одним із них є т. зв позначений покажчик (позначений індикатор). Зазвичай об’єкти та покажчики на ці об’єкти зберігаються в окремих частинах пам’яті. Однак нові типи вказівників дозволяють класам з невеликою кількістю даних зберігати об’єкти безпосередньо в покажчику. Цей крок усуває необхідність виділяти пам'ять безпосередньо для об'єкта, просто створіть вказівник і об'єкт всередині нього. Покажчики з тегами підтримуються лише в 64-розрядній архітектурі також через те, що в 32-розрядному покажчику більше не вистачає місця для зберігання достатньої кількості корисних даних. Тому iOS, на відміну від OS X, ще не підтримувала цю функцію. Однак із появою ARM64 ситуація змінюється, і iOS також наздогнала OS X у цьому плані.

Хоча покажчики мають довжину 64 біти, на ARM64 лише 33 біти використовуються для власної адреси покажчика. І якщо ми зможемо надійно демаскувати решту бітів покажчика, ми можемо використовувати цей простір для зберігання додаткових даних – як у випадку зі згаданими покажчиками з тегами. Концептуально, це одна з найбільших змін в історії Objective-C, хоча це не комерційна функція, тому більшість користувачів не знатимуть, як Apple просуває Objective-C вперед.

Що стосується корисних даних, які можуть зберігатися в просторі, що залишився такого тегованого вказівника, то, наприклад, Objective-C тепер використовує його для зберігання т.зв. кількість посилань (кількість посилань). Раніше підрахунок посилань зберігався в іншому місці пам’яті, у підготовленій для нього хеш-таблиці, але це могло уповільнити всю систему у випадку великої кількості викликів alloc/dealloc/retain/release. Таблицю потрібно було заблокувати через безпеку потоків, тому кількість посилань на два об’єкти у двох потоках не можна було змінити одночасно. Однак це значення заново вставляється в решту т.зв ISA показники. Це ще одна непомітна, але величезна перевага і прискорення в майбутньому. Однак цього неможливо досягти в 32-розрядній архітектурі.

Інформація про асоційовані об’єкти, чи є на об’єкт слабкі посилання, чи потрібно генерувати деструктор для об’єкта і т. д., також заново вставляється в місце, що залишилося покажчиків на об’єкти.Завдяки цій інформації Objective-C runtime здатний істотно прискорити час виконання, що відображається на швидкості кожної програми. Під час тестування це означає приблизно 40-50% прискорення всіх викликів керування пам’яттю. Просто перейшовши на 64-розрядні покажчики та використовуючи цей новий простір.

záver

Хоча конкуренти намагатимуться поширити ідею про непотрібність переходу на 64-розрядну архітектуру, ви вже знаєте, що це лише дуже неінформована думка. Це правда, що простий перехід на 64-розрядний без адаптації мови або програм до нього насправді нічого не означає - він навіть уповільнює всю систему. Але новий A7 використовує сучасний ARM64 з новим набором інструкцій, і Apple потрудилася модернізувати всю мову Objective-C і скористатися перевагами нових можливостей - отже, обіцяне прискорення.

Тут ми згадали велику кількість причин, чому 64-розрядна архітектура є правильним кроком вперед. Це ще одна революція «під капотом», завдяки якій Apple намагатиметься залишатися в авангарді не лише дизайном, користувальницьким інтерфейсом та багатою екосистемою, а й головним чином найсучаснішими технологіями на ринку.

Джерело: mikeash.com
.