- PVSM.RU - https://www.pvsm.ru -
Наверное, некоторые из вас слышали о халяве под названием x32 ABI [1].
Если вкратце, то это возможность использовать все преимущества 64-хбитной архитектуры, но при этом сохраняя 32-хбитные указатели. Потенциально при этом приложение будет расходовать меньше памяти, хоть и не сможет адресовать более 4 ГиБ памяти.
Пример. В своём коде вы определяете массив целых чисел и заполняете его значениями. Сколько при этом вы расходуете памяти? Если очень грубо изобразить, то получится примерно так:
32 бита: Указатель + Счётчик числа элементов + N целых чисел = N+2 32-хбитных числа
64 бита: Указатель + Счётчик числа элементов + N целых чисел = N+2 64-хбитных числа = 2N+4 32-хбитных числа
Вот инженеры и задумались: а что если попробовать использовать 32-хбитные указатели на 64-хбитной архитектуре? Архитектура X86-64 имеет систему команд CISC [2] и позволяет это сделать. В этом случае наш массив выше будет расходовать памяти 2N+3 вместо 2N+4. Экономия конечно же незначительная, но дело в том, что в современном коде количество разного рода указателей в структурах нередко доходит до десятка, и использование коротких указателей потенциально позволит экономить до 50% памяти (в идеальном случае).
Для тех кому надо расчёты точнее:
* Насколько большие массивы (и значения) в PHP? (Подсказка: ОЧЕНЬ БОЛЬШИЕ) [3]
* Сколько памяти потребляют объекты в PHP и стоит ли использовать 64-битную версию? [4]
Но как оказалось халявы не будет.
Было много комментариев к моей предыдущей статье [5] об x32 ABI. Некоторые из них интересные, другие же люди просто не понимают о чём пишут. У меня сложилось впечатление, что возникло что-то вроде культа карго [6] вокруг этой темы. Люди думают: «Зачем-то же они это делают, так что я тоже смогу это использовать», при этом техническая грамотность, чтобы оценить эту самую пользу, отсутствует.
Так что в том же духе, который я использовал, чтобы пройтись по ccache`у [7] почти четыре года назад (ух-ты, моему блогу уже столько лет, ну не молодец ли я?), я попробую развенчать мифы и заблуждения об этом x32 ABI.
Не совсем верно. Сейчас у нас только несколько результатов тестирования, выложенных теми, кто это самое ABI и создал. Конечно вы ожидаете, что те, кто потратил время, чтобы настроить систему, нашёл её интересной и более быстрой, но, честно говоря, у меня есть сомнения по поводу результатов, по причинам, которые будут ясны после прочтения нескольких следующих предложений.
Также интересно заметить, что, несмотря на то, что общие замеры оказались быстрее, разница — не принципиальная. И даже презентация Интела [8] показывает большие отличия только в сравнении с оригинальным x86, который и так понятно, что хуже x86-64.
Также эти результаты получены с помощью синтетических тестов, а не от реального использования системы, а вы знаете, если конечно знаете, что такие результаты могут врать с три короба.
Новый ABI генерирует меньший код, что значит, что больше инструкций попадёт в кеш процессора, а также у нас будут меньше файлы. Это абсолютно неверно. Генерируемый код, в общем, такой же как и для x86-64, так как не изменяется набор инструкций, просто изменяется так называемая модель данных, которая означает, что вы изменяете размер для long (и связанных типов) и размер указателей (но также меняется и размер доступного адресного пространства).
Теоретически верно, что если вы собираетесь использовать меньшие структуры данных, то их больше влезет в кеш данных (но не в кеш инструкций, будьте уверены (прим. пер.: CISC внутри себя сразу преобразует все короткие инструкции в длинные)), но разве это верный подход? По моему опыту, лучше сосредоточится на написании кода, который оптимальнее расположится в кеше, если ваш код пожирает кеш. Вы можете использовать утилиты dev-util/dwarves от Арнальдо (acme). pahole [9], например, скажет вам как ваши структуры данных будут разделены в памяти.
Также помните, что для совместимости системные вызовы будут оставлены такими же как в x86-64, что значит, что весь код ядра и системные структуры данных, которые вы будете использовать, будут такими же как и для x86-64. Что означает, что большое количество структур не поменяют свой размер в новом ABI (прим. пер.: бинарного интерфейса).
Наконец, если снова обратится к презентации, вы можете увидеть на слайде 24, что код x32 ABI может быть длиннее, чем оригинальный x86-код. Хорошо бы было, если бы они включили ещё и пример для x86-64 кода (так как я не владею VCISC(прим. пер.: имеется ввиду группа 64-хбитных инструкций из CISC)), но я думаю, что это и так один и тот же код.
Давайте для интереса сравним размер файла libc.so.6. Вот вывод утилиты rbelf-size из моего набора Ruby Elf [10]:
exec data rodata relro bss overhead allocated filename
1239436 7456 341974 13056 17784 94924 1714630 /lib/libc.so.6
1259721 4560 316187 6896 12884 87782 1688030 x32/libc.so.6
Запускаемый код даже больше в x32 варианте. Большое изменение конечно в структуре данных (data, rodata, relro and bss), так как указатели теперь сокращённые. Я честно говоря даже обеспокоен: «Как можно для Си библиотеки иметь так много указателей в собственных структурах?»; но это вопрос не по теме. Даже с учётом того, что указатели короче, разница не такая большая. В общем, вы будете иметь экономию что-то вроде 30 КиБ, что навряд ли изменит картину маппинга памяти.
Ну да, это ведь главный вопрос. Конечно структуры данных меньше с x32, так как для этого он и делался, в конце концов. Но главный вопрос вероятно будет: «Это так важно?»; я не думаю. Даже в примере выше с Си библиотекой, где разница ощутима, она всего около 20% занимаемого места. И это Си библиотека! Библиотека, которая предполагает, что вы будете писать гораздо меньшие интерфейсы.
Сейчас если вы прибавите к этому все возможные библиотеки, то, возможно, вы можете сэкономить пару мегабайт данных, конечно же, но вы также должны учесть все проблемы портирования, которые я собираюсь обсудить скоро. Да, это правда, что С++ и большая часть языков с виртуальной машиной будут иметь меньше трудностей, особенно при копировании объектов, благодаря уменьшенным указателям, но пока мы может утверждать это с большой натяжкой. В особенности с тех пор как большинство ваших буферов данных должны быть выравнены хотя бы по 8 байт (64 бита), чтобы использовать новые инструкции. И вы уже выравниваете их по 16 байт (128 бит), чтобы использовать некоторые наборы инструкций SIMD [11].
И для тех, кто думает, что x32 сэкономит место на диске. Запомните, что вы не можете иметь «чистую» x32 систему, то что вы получите — будет смешение трёх подходов: x86, x86-64 и x32.
Да, конечно, это, возможно, правда. Но серьёзно, вы действительно беспокоитесь о размере указателей? Если вы реально хотите убедиться, что приложение не использует больше, чем определённое количество памяти, используйте системные лимиты! Они, безусловно, менее «тяжёлые» чем создание нового ABI в целом.
Интересно, что есть 2 разных, противоположных подхода для приложений в полном 64-хбитном адресном пространстве с памятью меньше чем 4 ГиБ:
(Прим. пер.: автор имеет ввиду 64-хбитный long)
И, конечно же, решение — создание нового ABI для этого, по мнению некоторых людей.
Я не собираюсь говорить, что много людей для приложений до сих пор используют long, не задумываясь о том, зачем они это делают. Возможно, они имеют небольшие диапазоны чисел, которые хотят использовать, и всё же при этом они используют большие типы, такие как long, так как возможно изучали программирование на системах, которые используют long как синоним int, или даже на системах где long 32-хбитный, а int — 16-ибитный (привет MS-DOS!).
Решение этой проблемы простое — используйте стандартные типы, предоставленные stdint.h, такие как uint32_t и int16_t. Так вы всегда будете использовать размер данных, который ожидаете. Это также работает на большем количестве систем, чем вы ожидали, и работает с FFI [14] и другими техниками.
Это сказали мне несколько людей после моего предыдущего поста, где я жаловался, что в новом ABI мы потеряем большую часть ассемблерных вставок. Это утверждение может быть верно, но на самом деле их не так уж и мало как вы думаете. Даже если исключить все мультимедийные программы, криптографические программы, которые неплохо используют SIMD через ассемблерные вставки (а не через оптимизации компилятора).
Также есть проблема с ассемблерными вставками в такой вещи как Ruby, где Ruby 1.9 не компилится на x32. С Ruby 1.8 ситуация более интересная, потому что он компилится, но выбрасывает segfaults at runtime при запуске. Не напоминает вам ничего? [15]
Кроме того, Си библиотека сама по себе идёт с большим количеством ассемблерных вставок. И единственная причина почему вам не надо так много портировать проста — H.J. Lu, который заботится о большей части из них, — один из авторов нового ABI, что означает, что код уже портирован.
Ну хорошо, я не упоминал об этом ранее, но это одно из заблуждений, которое я заметил перед тем, как меня закидали камнями. К счастью, презентация [8] поможет в этом. Слайд 22 чётко даёт понять, что новый ABI не совместим. Среди прочего вы можете заметить, что ABI по крайней мере исправляет некоторые фактические ошибки в x86, включая использование 32-хбитных типов данных для off_t и другие. Опять же, я немного касался этой темы два года назад [16].
Нет, опять же обратимся к слайдам, в особенности к слайду 10. Это явно сделано для проприетарных систем, чем вообще для замены x86-64! Ну как вы теперь себя чувствуете?
Это не тот случай. Портирование требует решить ряд других вопросов, и ассемблерные вставки — просто вершина айсберга. Ломать понятие того, что в x86-64 указатели 64-хбитные, — само по себе большая задача, но не такая большая как можно предположить на первый взгляд (и также для Windows), по сравнению с реализацией FFI стиля Си биндингов. Помните, я говорил, что это не простой ответ [17]?
Интересно, что только один процессор, который по утверждению Интела в презентации работает лучше на 32-хбитных инструкциях, — это Atom. Цитирую: «Задержки на 64-хбитных IMUL операциях вдвое выше, чем на 32-хбитных на Atom`е».
Итак, что же такое IMUL? Это операция знакового умножения. Вы умножаете указатели? Это бессмысленно. Кроме того, указатели не знаковые. И вы говорите мне, что вы больше беспокоитесь о платформе (Atom`е), которая имеет большие задержки, когда люди используют 64-хбитные данные вместо положенных 32-хбитных? И ваше решение для этой проблемы — создание нового ABI, где тяжело использовать 64-хбитные типы. И всё это вместо того, чтобы просто исправить в программе то, что порождает эти проблемы?
Я вероятно должен остановиться на этом, так как этот последний комментарий о Atom`е и IMUL`е порадует многих людям, которые лишь поверхностно понимают новый интерфейс.
Автор: gnomeby
Источник [18]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/linux/27873
Ссылки в тексте:
[1] x32 ABI: http://ru.wikipedia.org/wiki/X32_ABI
[2] систему команд CISC: http://ru.wikipedia.org/wiki/CISC
[3] Насколько большие массивы (и значения) в PHP? (Подсказка: ОЧЕНЬ БОЛЬШИЕ): http://habrahabr.ru/post/141093/
[4] Сколько памяти потребляют объекты в PHP и стоит ли использовать 64-битную версию?: http://habrahabr.ru/post/161629/
[5] к моей предыдущей статье: http://blog.flameeyes.eu/2012/06/is-x32-for-me-short-answer-no
[6] культа карго: http://ru.wikipedia.org/wiki/%D0%9A%D1%83%D0%BB%D1%8C%D1%82_%D0%BA%D0%B0%D1%80%D0%B3%D0%BE
[7] пройтись по ccache`у: http://blog.flameeyes.eu/2008/06/debunking-ccache-myths
[8] презентация Интела: http://linuxplumbersconf.net/2011/ocw//system/presentations/531/original/x32-LPC-2011-0906.pptx
[9] pahole: http://lwn.net/Articles/206805/
[10] Ruby Elf: http://www.flameeyes.eu/projects/ruby-elf
[11] SIMD: http://ru.wikipedia.org/wiki/SIMD
[12] ASLR: http://ru.wikipedia.org/wiki/ASLR
[13] Prelink: http://en.wikipedia.org/wiki/Prelink
[14] FFI: http://en.wikipedia.org/wiki/Foreign_function_interface
[15] Не напоминает вам ничего?: http://blog.flameeyes.eu/2010/09/not-all-failures-are-caused-equal
[16] два года назад: http://blog.flameeyes.eu/2010/12/another-good-reason-to-use-64-bit-installations-large-file-support-headaches
[17] не простой ответ: http://blog.flameeyes.eu/2012/03/why-foreign-function-interfaces-are-not-an-easy-answer
[18] Источник: http://habrahabr.ru/post/170407/
Нажмите здесь для печати.