Solr + Eclipse + Jetty + пользовательские JSP

Как указывает ответ Триллиана, AMD K8 и K10 имеют проблему с предсказанием ветвления , когда ret является целью ветвления или следует условной ветви.

Оптимизация AMD Руководство для K10 (Barcelona) рекомендует 3-байтные ret 0 в тех случаях, которые выталкивают нулевые байты из стека, а также возвращаются. Эта версия значительно хуже, чем rep ret для Intel. По иронии судьбы, это также хуже, чем rep ret на более поздних процессорах AMD (Bulldozer и далее). Поэтому хорошо, что никто не изменил использование ret 0 на основе обновления руководства по оптимизации AMD Family 10.


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

gcc по-прежнему использует rep ret по умолчанию (без -mtune=intel или -march=haswell или что-то еще). Таким образом, у большинства Linux-двоичных файлов есть repz ret.

gcc, вероятно, перестанет использовать rep ret через несколько лет, как только K10 будет полностью устаревшим. Спустя еще 5 или 10 лет почти все двоичные файлы будут построены с использованием gcc более новой версии. Еще через 15 лет производитель ЦП может подумать о том, чтобы повторить последовательность байтов f3 c3 как (часть) другой команды.

Все еще будут существовать двоичные файлы с закрытым исходным кодом, использующие rep ret, которые не будут Однако у вас есть более свежие сборки, и кому-то нужно продолжать работать. Поэтому какая бы новая функция f3 c3 != rep ret не была частью, должна была бы быть отключена (например, с настройкой BIOS), и эта настройка действительно изменит поведение инструкции-декодера, чтобы распознать f3 c3 как rep ret. Если эта обратная совместимость для устаревших двоичных файлов невозможна (потому что она не может быть эффективно реализована с точки зрения мощности и транзисторов), IDK, на какой временной шкале вы будете смотреть. Гораздо больше, чем 15 лет, если это не было процессором только для части рынка.

Так что безопасно использовать rep ret, потому что все остальные уже делают это. Использование ret 0 - плохая идея. В новом коде может еще неплохо использовать rep ret еще пару лет. Вероятно, не так уж много процессоров AMD PhenomII по-прежнему вокруг, но они достаточно медленны без лишних ошибочных ошибок обратного адреса или проблемы с проблемой.


Стоимость довольно мала. В большинстве случаев он не занимает лишнего места, потому что в любом случае обычно его заполняет nop. Однако в тех случаях, когда это приводит к дополнительному заполнению, это будет наихудший случай, когда требуется 15 бит заполнения для достижения следующей границы 16B. В этом случае gcc может выравниваться только на 8B. (с .p2align 4,,10; для выравнивания до 16B, если для этого потребуется 10 или меньше nop-байтов, тогда .p2align 3 всегда будет выровняться с 8B. Используйте gcc -S -o- для вывода asm-выхода в stdout, чтобы увидеть, когда он это делает.)

Итак, если мы предположим, что один из 16 rep ret в конечном итоге создает дополнительное дополнение, в котором ret просто ударил бы нужное выравнивание и что дополнительное заполнение переходит на границу 8B, это означает, что каждый rep имеет среднюю стоимость 8 * 1/16 = половина байта.

rep ret не используется достаточно часто, чтобы что-то значило. Например, firefox со всеми библиотеками, которые он отобразил, имеет только ~ 9k экземпляров rep ret. Так что это около 4k байт, во многих файлах. (И меньше оперативной памяти, чем это, так как многие из этих функций в динамических библиотеках никогда не вызывают.)

# disassemble every shared object mapped by a process.
ffproc=/proc/$(pgrep firefox)/
objdump -d "$ffproc/exe" $(sudo ls -l "$ffproc"/map_files/ |
       awk  '/\.so/ {print $NF}' | sort -u) |
       grep 'repz ret' -c
objdump: '(deleted)': No such file  # I forgot to restart firefox after the libexpat security update
9649

Что считается rep ret во всех функциях во всех библиотеках, которые отображал firefox, а не только функции, которые он когда-либо звонил. Это несколько актуально, потому что более низкая плотность кода по функциям означает, что ваши вызовы распределены по большему количеству страниц памяти. ITLB и L2-TLB имеют ограниченное количество записей. Локальная плотность имеет значение для L1I $ (и uop-cache от Intel). Во всяком случае, rep ret имеет очень незначительное влияние.

Мне потребовалась минута, чтобы подумать о причине, что /proc//map_files/ недоступен для владельца процесса, но /proc//maps. Если UID = корневой процесс (например, из двоичного файла suid-root) mmap(2) sa 0666, который находится в каталоге 0700, то делает setuid(nobody), любой, кто работает с этим двоичным файлом, может обойти ограничение доступа, наложенное отсутствием x for other разрешение на каталог.

0
задан Winston 22 February 2015 в 15:11
поделиться