Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

ARM64 и Ты

Anna | 2.07.2014 | нет комментариев

Несколько запоздалый перевод заинтересовавшего меня блогпоста о том, что в реальности дает 64-битность процессора в iPhone без маркетинговой шелухи. Если текст покажется вам слишком явственным, пропустите часть «Базовые превосходства и недочеты».

Как только был анонсирован iPhone 5S, технические медия были переполнены недостоверными статьями. К сожалению, написание отличных статей занимает время, а мир технической журналистики огромнее ценит скорость, чем достоверность. Сегодня, по просьбе нескольких своих читателей, я коротко выскажу, что дает 64-bit ARM в iPhone 5S в плане продуктивности, вероятностей и разработки.

64 бита

Давайте для начала разглядим что, собственно, 64-битность обозначает. С этим термином связанно много путаницы, в основном из-за того, что нет цельного устоявшегося определения. Впрочем, существуетвсеобщие осознавание этого термина. «Битность» обыкновенно обозначает либо размер числового регистра, либо размер указателя. К счастью, для большинства современных процессоров, их размер совпадает. Таким образом, 64-битность обозначает что процессор владеет 64-битными числовыми регистрами и 64-битными указателями.

Значимо также подметить, что 64-битность не обозначает, т.к. и тут есть много недопонимания. Выходит, 64-битность не определяет:

  1. Размер адресуемой памяти. число бит, реально задействованных в указателе на связано с битностью процессора. Процессоры ARM использует от 26 до 40 бит, и это число может изменяться в отрыве от битности процессора.
  2. Ширину шины данных. Объем данных, запрашиваемых из RAM либо кэша также не связано с битностью. Отдельные процессорные инструкции могут запрашивать произвольные объемы данных, но объем реально одновременно запрашиваемых данных может отличаться, либо разбивая запросы на части, либо запрашивая огромнее чем нужно. Теснее в iPhone 5 размер запрашиваемого блока данных составляет 64 бита, а у PC доходит до 192 бит.
  3. Все что связано с вычислениями с плавающей запятой. Регистры FPU не связанны с архитектурой и процессоры ARM применяли 64-битные регистры задолго до ARM64.

Базовые превосходства и недочеты

Если вы будете сопоставлять одинаковые процессоры 32 и 64 битные CPU, вы не обнаружит крупных отличий, так что значительность перехода Apple на 64-битные ARM несколько преувеличена. Это значимый шаг, но значимый, в основном, из-за особенностей ARM и спецификой применения процессора компанией Apple. Тем не менее, некоторые отличия имеются. Самым явственным является 64-битные числовые регистры больше результативно работают с 64-битными числами. Вы можете трудиться с 64-битными числами и на 32-битном процессоре, но это обыкновенно приводит к работе с двумя 32-битными частями, что работает ощутимо неторопливей. 64-битные процессоры, обыкновенно, исполняют операции над 64-битными числами также стремительно как и над 32-битными, так что код энергично использующий вычисления с 64-битными числами будет трудиться гораздо стремительней.

Не смотря на то, что 64-битность не связана напрямую с объемом адресуемой памяти, она гораздо облегчает применение большого объема RAM в рамках одной программы. Программа, запущенная на 32-битном процессоре может адресовать не огромнее 4GB адресного пространства. Часть памяти выделена под операционную систему и типовые библиотеки, что оставляет 1-3GB на саму программу. Если у 32-битной системы огромнее 4GB RAM, то применение каждого этого адресного пространства для программы гораздо усложняется. Вам придется заняться махинациями как бы последовательного отображение различных частей RAM на часть виртуального адресного пространства либо разбивание одной программы на несколько процессов.

Сходственные трюки весьма трудозатраны и могут крепко замедлить систему, так что немного кто из программистов реально их использует. На практике, на 32-битных процессорах всякая программа применяют до 1-3GB RAM, а каждая ценность в обладании большего объема физической оперативной памяти заключается в вероятности огромнее запускать программ единовременно и вероятность кеширования огромнее данных с диска.

Увеличение объема адресного пространства благотворно и для систем с небольшим объемом оперативной памяти — memory-mapped файлы, размеры которых могут быть  и огромнее доступной оперативной памяти, т.к. операционная система реально загружает только те части файла, к которым производились обращения и, помимо того, может «вытеснять» заоиться об бинарной обратной совместимости при таких изменениях, это чудесное время Дабы внести метаморфозы которые в отвратном случае «поломали» теснее существующие приложения.

В Max OS X 10.7 Apple ввела меченные указатели (tagged pointers). Меченные указатели разрешают беречь некоторые классы с небольшим числом данных в экземпляре напрямую в указателе. Это разрешает избежать выделений памяти в некоторых случаях, скажем NSNumber и может дать значительный приход продуктивности. Меченные указатели поддерживаются только на 64-битной платформе, Отчасти из-за вопроса продуктивности, а Отчасти из-за того что в 32-битном указателе не так много остается места под «метки». Видимо по-этому, у iOS не было поддержки меченных указателей. Таким образом, в ARM64 в рантайме Objective-C включена помощь меченных указателей, что дает те же превосходства, что в Mac.

Не смотря на то, что размер указателя составляет 64 бита, не все эти биты на самом деле применяются. В Mac OS X на x86-64 применяется только 47 битов. В iOS на ARM64 применяется еще поменьше — только 33 бита. Если маскировать эти биты всякий раз перед применением то дозволено применять остальные биты Дабы беречь добавочные данные. Это дозволило внести одно из самых существенных изменений в рантайм Objective-C за всю его историю.

Переосмысленние укозателя isa

Огромная часть информации в этой сегменты почерпана из статьи Грега Паркера. Во первых, для освежения памяти: объекты в Objective-C представляют выделенные блоки памяти. 1-й часть, размером с указатель, это isa. Обыкновенно, isa это указатель на класс объекта. Дабы узнать огромнее о том, как объекты хранятся  в памяти, читайте мою иную статью.

Применять каждый размер указателя на указатель isa несколько небережливо, исключительно на 64-битной платформе, которая не использует все 64-бита. ARM64 на iOS реально использует 33 бита, оставляя 31 бит для других пророческой. Классы в памяти выровнены по границе 8 байт, так что последние 3 бита дозволено отбросить, что дает 34 бита из isa доступные для хранения дополнительной информации. И Apple-овский рантайм в ARM64 использует это для возрастания продуктивности.

Вероятно, самой главной оптимизацией стало встраивание (inline) счетчика ссылок. Фактически все объекты в Objective-C владеют счетчиком ссылок (за исключение неизменяемых объектов, таких как литералы NSString) и операции retain/release, которые меняют данный счетчик случаются дюже Зачастую. Это исключительно критично для ARC, тот, что вставляет вызовы retain/release Почаще, чем бы это делал программист. Таким образом, высокая продуктивность retain/release способов весьма значима.

Обыкновенно, счетчик ссылок не хранится в самом объекте. Дозволено было бы беречь счетчик ссылок в самом объекте, но это заняло бы слишком много места. Это не так значимо теперь, но тогда, давным-давно, это было крайне значительно. Из-за этого, счетчик ссылок хранится во внешней хеш-таблице. Всякий раз при вызове retain, производятся следующие действия:

  1. Получить глобальную хещ-таблицу счетчиков указателей
  2. Заблокировать хеш-таблицу, Дабы операция была потокобезопасной
  3. Обнаружить в хеш-таблице счетчик для заданного объекта
  4. Увеличить счетчик на один и сберечь его обратно в таблицу
  5. Отпустить блокировку хеш-таблицы

Довольно медлительно! Реализация хеш-таблицы счетчиков сделана дюже результативной, для хеш-таблицы, но это все еще гораздо неторопливей прямого доступа к памяти. В ARM64, 19 бит указателя isa применяются для хранения счетчика ссылок. Это обозначает, что вызов retain упрощается до:

  1. Произвести атомарное увеличение части isa-поля

И все! Это должно быть значительно, значительно стремительней.

На самом деле все несколько труднее из-за различных краевых случаев, которые тоже нужно обработать. По-настоящему последовательность действий примерно такая:

  1. Конечный бит в isa говорит, применяются ли добавочные биты в isa для хранения счетчика ссылок. Если нет, применяется ветхий алгорифм с хеш-таблицами.
  2. Если объект теснее удаляется, ничего не выполняется
  3. Если счетчик переполняется (что случается редко, но абсолютно допустимо при 19 битах), применяется ветхий алгорифм с хеш-таблицей
  4. Произвести атомарное метаморфоза isa на новое значение

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

Применение оставшихся неиспользованных под счётчик ссылок биты в isa дозволило ускорить деаллокацию объектов. Теоретически, необходимо совершить кучу действий когда объект в Objective-C удаляется и вероятность пропустить непотребные может гораздо увеличить эффективность.  Эти шаги:

  1. Если у объекта не было ассоциированных объектов, установленных применяя objc_setAssociatedObject, их не нужно удалять.
  2. Если объект не владеет C -деструктором (тот, что вызывается при dealloc), его тоже не необходимо вызывать.
  3. Если на объект ни разу не ссылались слабым (__weak) указателем, то эти указатели не нужно обнулять.

Прежде, все эти флаги хранились в классах. Скажем, если хоть один экземпляр класса когда-либо хранил ассоциированные объект, то все экземпляры этого класса удаляли ассоциированные объект при деаллокации. Отслеживание этих флагов для всякого экземпляра в отдельности дозволило вызывать соответствующие способы только для тех экземпляров, для которых это подлинно было необходимо.

Суммарно, это значительный выигрыш. Мои бенчмарки показали, что создание и удаление простого объекта  занимает 380нс на 5S в  32-битном режиме, в то время как в 64-битном только 200нс. Если хоть один экземпляр когда-либо имел слабую ссылку на себя, то в 32-битном режим время удаления для всех возрастало до 480нс, в то время как в 64-битном режиме время не осталось в районе 200нс для всех экземпляров, на которых слабых ссылок не было.

Короче говоря, совершенствования в рантайме таковы, что в 64-битном режиме время аллокации занимают 40-50% от времени аллокации в 32-битном режиме. Если ваше приложение создает и удаляет много объектов, это может оказаться значительным.

Завершение

64-битность A7 не легко маркетинговая уловка, но это и не удивляющий воображение прорыв тот, что дозволит создавать новейший класс приложений. Правда, как неизменно, лежит посередине.

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

Зодчество ARM изменилась не только в 64-битности. Увеличенное число регистров и пересмотренный, модернизированный комплект инструкций дает недурной приход продуктивности по сопоставлению с 32-битным ARM.

Apple использовала переход на новую архитектуру для совершенствования в рантайме. Основное метаморфоза — встраиваемый (inlined) счетчик ссылок, тот, что разрешает избежать дорогого поиска по хеш-таблице. Так операции retain/release дюже часты в Objective-C, это значительный выигрыш. Удаление источников в зависимости от флагов делает удаление объектов примерно вдвое стремительней. Меченные (tagged) указатели также добавляют продуктивность и сокращают потребление памяти.

AMD64 — славное добавление от Apple. Мы все знали, что это рано либо поздно случится, но немного кто ждал что так скоро. Но оно есть, и это отменно.

Источник: programmingmaster.ru

Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB