2014-02-11 3 views
11

У меня есть простая тестовая программа, которая загружает регистр xmm с помощью команды movdqu , доступ к данным через границу страницы (OS = Linux).Инструкция MOVDQU + граница страницы

Если отображается следующая страница, это работает отлично. Если это не , тогда я получаю SIGSEGV, который, вероятно, ожидается.

Однако это уменьшает полезность невыравниваемых нагрузок довольно . Кроме того, инструкции SSE4.2 (например, pcmpistri), которые допускают для ссылок на неравнозначные ссылки памяти, также проявляют это поведение .

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

Еще одно замечание - она ​​появляется на реализацию библиотеки GNU C для 64-битном Linux имеет __strcmp_sse42 вариант, который, как представляется, использовать инструкцию pcmpistri более безопасным способом. Реализация эта strcmp довольно сложна, но, как представляется, она тщательно пытается использовать , чтобы избежать проблемы с границей страницы. Я не уверен, что это связано с проблемой , описанной выше, или это просто побочный эффект от попыток получить более высокую производительность путем выравнивания данных.

В любом случае, вопрос в первую очередь - где я могу узнать больше по этому вопросу? Я набрал «границу страницы переходов movdqu» и каждый вариант, который я могу придумать Google, но не нашел ничего особенно полезного. Если кто-нибудь может указать мне на дополнительную информацию на это было бы весьма полезно.

+0

Реализация '__strcmp_sse42', вероятно, делает это, чтобы избежать хита производительности при пересечении границы страницы. Процессоры Intel (не уверены в последних) имели историю ужасающей производительности при неверно выровненных доступах, которые пересекают границы страниц. Проблема с ошибкой страницы должна быть неактуальной. – Mysticial

+1

Мне очень любопытно ответить на этот вопрос. В Руководстве по оптимизации Intel (раздел 10.3.6) говорится, что «Unaligned 128-bit SIMD-память может получать границу перекрестной границы данных, поскольку системное программное обеспечение управляет правами доступа к памяти со степенью детализации страницы». Может быть, попробуйте воспроизвести ту же ошибку на некоторых других ОС? –

+1

Или, скорее, ОС ответит на ошибку страницы и сделает ее невидимой для приложения (в отличие от огромного удара производительности). Или сбой приложения, если он не назначен. В этом случае стандартным UB является доступ к нераспределенной памяти. – Mysticial

ответ

8

Во-первых, любой алгоритм, который пытается получить доступ к немаркированному адресу, вызовет SegFault. Если в потоке кода, отличном от AVX, используется 4 байтовая загрузка для доступа к последнему байту страницы и первым 3 байтам «следующей страницы», которые не были сопоставлены, тогда это также вызовет SegFault. Нет? Я считаю, что «проблема» в том, что регистры AVX (1/2/3) намного больше, чем «типичные», что алгоритмы, которые были небезопасными (но ушли с ним), попадают, если они тривиально распространяются на более крупные регистры ,

У согласованных нагрузок (MOVDQA) никогда не может быть этой проблемы, поскольку они не пересекают границы их собственного размера или больше. Несбалансированные нагрузки CAN могут иметь эту проблему (как вы уже отметили) и «часто». Причиной этого является то, что команда определила для загрузки полного размера целевого регистра. Вы должны внимательно изучить типы операндов в определениях команд. Неважно, какая часть данных вам интересна. Это важно для определения инструкции.

Однако ...

AVX1 (SandyBridge) добавил «замаскированный ход» способность, которая медленнее, чем MOVDQA или movdqu, но не будет (архитектурно) доступ неотображенное страницу, пока маска не включена часть доступа, которая попала бы на эту страницу. Это предназначено для решения этой проблемы. В целом, двигаясь вперед, кажется, что маскированные части (см. AVX512) нагрузок/хранилищ также не будут вызывать нарушения доступа к IA.

(Это облом о поведении PCMPxSTRx. Может быть, вы могли бы добавить 15 байт дополнения к вашим «строке» объектам?)

2

Столкнувшись с подобной проблемой библиотекой я писал, I got some information от очень полезного вклада ,

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

Поскольку мы никогда не читаем строку, мы не можем потенциально заблудиться на защищенной странице.

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

Смежные вопросы