2016-11-09 5 views
0

В документе GCC here указано использование _buitin_prefetch.Каков эффект второго аргумента в _builtin_prefetch()?

Третий аргумент совершенен. Если это 0, компилятор генерирует команду prefetchtnta (% rax) Если это 1, компилятор генерирует команду prefetcht2 (% rax) Если это 2, компилятор генерирует команду prefetcht1 (% rax) Если это 3 (по умолчанию) , компилятор генерирует команду prefetcht0 (% rax).

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

Но второй аргумент, похоже, не имеет никакого эффекта.

__builtin_prefetch(&x,1,2); 
__builtin_prefetch(&x,0,2); 
__builtin_prefetch(&x,0,1); 
__builtin_prefetch(&x,0,0); 

Выше образец фрагмент кода, который генерируется:

Ниже сборка:

27: 0f 18 10    prefetcht1 (%rax) 
    2a: 48 8d 45 fc    lea -0x4(%rbp),%rax 
    2e: 0f 18 10    prefetcht1 (%rax) 
    31: 48 8d 45 fc    lea -0x4(%rbp),%rax 
    35: 0f 18 18    prefetcht2 (%rax) 
    38: 48 8d 45 fc    lea -0x4(%rbp),%rax 
    3c: 0f 18 00    prefetchnta (%rax) 

можно наблюдать изменение в опкоды WRT 3-го аргумента. Но даже если я изменил второй аргумент (который указывает чтение или запись), код сборки остается тем же. < 27,2a> и < 2e, 31>. Так что это не дает никакой информации машине. Тогда в чем смысл второго аргумента?

+2

Документация очень Чисто. Какие команды он генерирует для определенной архитектуры, конечно, зависит от доступных функций. Для некоторых архитектур он вообще не будет генерировать никаких инструкций. Итак, вы проверили, какие инструкции предварительной выборки заданы для вашей целевой цели x86? Что они на самом деле делают? И как они связаны с аргументами? Инструкции по эксплуатации для Intel и AMD доступны для бесплатной загрузки. – Olaf

ответ

4

Из той же ссылке вы публикуемую:

Есть два необязательных аргумента, RW и местонахождение. Значение rw - постоянная времени компиляции или ноль; означает, что предварительная выборка готовится для записи на адрес памяти и нуль, по умолчанию означает, что предварительная выборка готовится к чтению.

Архитектура x86 не имеет никакого различия между префиксами чтения и записи.
Это не означает, что вы должны игнорировать второй аргумент, поскольку код записи на C выполняется для улучшения переносимости. Даже если в вашей машине второй аргумент не используется, его можно использовать при компиляции в разные архитектуры.

EDIT Как @PeterCordes отметил в своем комментарии, x86 на самом деле есть инструкция предвыборки в ожидании записи.
Он отличается от других инструкций предварительной выборки, поскольку он делает недействительными другие кэшированные объекты выбранной линии (и устанавливает ее в исключительное состояние).

+1

PREFETCHW существует на процессорах AMD и Intel с Broadwell. Отличная точка зрения, что даже если ваша текущая цель компиляции не поддерживает ее, вы все равно должны правильно выражать свое намерение, чтобы вы могли получить хорошие asm для других целей. –

+0

Спасибо, @ Петр, я полностью пропустил это. –

+0

Спасибо за ваши ответы. Какая польза от указания чтения/записи во втором аргументе, по аппаратным средствам?? Как аппаратные средства обрабатывают разные вещи? Он имеет те же записи MSHR. Я просто хочу знать, как аппаратные средства показывают разницу в лечении этих R и W. !! – ANTHONY

3

Как отмечает Маргарет, один из аргументов - rw. Базовая x86-64 (SSE2) не включает в себя инструкцию записи prefetch, но они существуют как расширение ISA. Как обычно, компиляторы не будут использовать их, если вы не скажете, что их компилируете для целевой, которая ее поддерживает.

Две инструкции: PREFETCHW и PREFETCHWT1.

PREFETCHW первоначально появился в 3DNow! AMD, но имеет свой собственный бит функции, так что процессоры могут указать поддержку для него, но не другие инструкции 3dNOW (упакованные - в MMX regs).

Я не уверен, что какие-либо процессоры поддерживают PREFETCHWT1. Основываясь на this mailing list post, я думаю, что это, вероятно, в Xeon PHI изначально и/или связано с AVX512.


__builtin_prefetch(p,1,2); компилирует следующим образом:

  • prefetcht1 без каких-либо опций -m или -march=haswell или старшем Intel.
  • PREFETCHW с целью AMD, например -march=k8 или -march=bdver2 (Piledriver).
  • PREFETCHW с -march=broadwell или более новой Intel SnB-family.
  • PREFETCHWT1 с -mprefetchwt1. (Если PREFETCHW также доступна, GCC использует его для местности = 3, но PREFETCHWT1 для местности < = 2.)

Проверьте это на Godbolt compiler explorer, для -march=haswell VS. -march=broadwell -mprefetchwt1. Или измените сами компилятор.

Странно, gcc x86 target options, кажется, не упоминает отдельный переключатель, чтобы включить PREFETCHW; он включен только как часть -march=whatever. Это SO answer использует -mprfchw, чтобы включить его.

Также обратите внимание, что его 0F 0D r/m8 machine-code encoding decodes as a multi-byte NOP на процессорах, у которых нет PREFETCHW или 3DNow! Функция-бит. На ранних 64-битных процессорах Intel это незаконная инструкция. (В более новых версиях Windows требуется, чтобы PREFETCHW выполнялся без сбоев, и в этом контексте люди говорят о процессоре, поддерживающем PREFETCHW, даже если он работает как NOP.

Возможно, предпочтительнее использовать предварительную выборку для чтения, а не NOP. Но вы, вероятно, не хотите делать PREFETCHW и PREFETCHT0, потому что слишком много инструкций по предварительной выборке не очень хорошо. (особенно для Intel IvyBridge, у которого есть некоторая ошибка производительности для пропускной способности prefetch-инструкции. Но OTOH, он будет запускать PREFETCHW как NOP, поэтому в этом случае вы получаете только одну предварительную выборку.)

+0

Благодарим за отзыв. Где указать, что -march = -xxxxx.? Что этот параметр марша указывает точно, целевая машина/архитектура? – ANTHONY

+2

@ANTHONY: В командной строке gcc, во время компиляции, очевидно. https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html. Я не думаю, что это имеет значение во время соединения, просто переходя от '.c' к' .o' (или непосредственно к исполняемому файлу). Он сообщает gcc, какие инструкции ему разрешено использовать, а также устанавливает '-mtune ='. –

+0

Точнее, более старые версии Windows, эмулированные для 3DNow! prefetch для более старых процессоров Intel. –