Происходит ли сериализация одновременных обращений к глобальной памяти по одному адресу при наличии уровней кэша L1 и L2?

Исходя из того, что я знаю, когда потоки деформации обращаются к одному и тому же адресу в глобальной памяти, запросы сериализуются, поэтому лучше использовать постоянную память. Происходит ли сериализация одновременных обращений к глобальной памяти, когда GPU оборудован уровнями кэша L1 и L2 (в архитектуре Fermi и Kepler)? Другими словами, когда потоки деформации получают доступ к одному и тому же глобальному адресу памяти, получает ли 31 поток деформации выгоду от существования кэша, поскольку один поток уже запросил этот адрес? Что происходит, когда доступ является чтением, а также когда доступ является записью?

1 ответ

Решение

Одновременный глобальный доступ к одному и тому же адресу потоками в одной и той же деформации в Ферми и Кеплере не сериализуется. У чтения деформации есть механизм широковещания, который удовлетворяет всем таким чтениям из одной операции чтения из кэша без влияния на производительность. Производительность такая же, как если бы это было полностью объединенное чтение. Это верно независимо от специфики кэша, например, это верно, даже если кэширование L1 отключено.

Производительность одновременной записи не указана (AFAIK), но поведенчески, одновременные записи всегда сериализуются, а порядок не определен.

РЕДАКТИРОВАТЬ, отвечая на дополнительные вопросы ниже:

  1. Даже если все потоки в деформации записывают одно и то же значение в один и тот же адрес, он сериализуется? Разве нет механизма записи вещания, который распознает такую ​​ситуацию?

Не существует механизма широковещательной записи, который просматривает все одновременные записи, чтобы увидеть, все ли они одинаковы, а затем предпринимает некоторые действия, основываясь на этом. Правильный ответ заключается в том, что запись происходит в неопределенном порядке, а характеристики производительности не определены. Очевидно, что если все записываемые значения одинаковы, вы можете быть уверены, что значение, которое заканчивается в местоположении, будет этим значением. Но если вы спрашиваете, свернута ли операция записи в один цикл или требуется несколько циклов для завершения, это фактическое поведение не определено (недокументировано) и фактически может варьироваться от одной архитектуры к другой (например, cc1.x может сериализировать таким образом, чтобы все записи выполнялись, тогда как cc2.x может "сериализоваться" таким образом, что одна запись "выигрывает", а все остальные отбрасываются, не потребляя фактических циклов.) Опять же, производительность не документирована / не определено, но поведение, наблюдаемое программой, определено.

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

__constant__ память использует постоянный кеш, который является выделенным компонентом оборудования, доступным для каждой SM, и кэширует определенный раздел глобальной памяти только для чтения. Этот HW-кэш физически и логически отделен от кеша L1 (если он существует и включен) и кеша L2. Для Fermi и более поздних версий оба механизма поддерживают широковещательную передачу при чтении, а для постоянного кэша это предпочтительный шаблон доступа, поскольку постоянный кэш может обслуживать только один доступ на чтение за цикл (т.е. не поддерживает всю строку кэширования, прочитанную деформацией). Любой механизм может "попасть" в кеш (если есть) или "пропустить" и вызвать глобальное чтение. При первом чтении заданного местоположения (или строки кэша) в другом кэше будут запрошенные данные, и поэтому он будет "пропускать" и запускать чтение из глобальной памяти для обслуживания доступа. После этого, в любом случае, последующие чтения будут обслуживаться из кэша, при условии, что соответствующие данные не будут удалены в промежуточный период. Для ранних устройств cc1.x постоянная кэш-память была довольно ценной, поскольку у этих ранних устройств не было кеша L1. Для Ферми и за его пределами основной причиной использования постоянного кэша было бы, если бы были доступны идентифицируемые данные (т.е. только для чтения) и шаблоны доступа (один и тот же адрес на деформацию), тогда использование постоянного кэша предотвратит прохождение этих чтений через L1 и, возможно, выселять другие данные. Фактически вы несколько увеличиваете объем кэшируемого пространства, по сравнению с тем, что L1 может поддерживать в одиночку.

Другие вопросы по тегам