2016-02-24 21 views
0

У меня есть приложение, в котором мне нужно транслировать одно (не постоянное, просто старое) значение в глобальной памяти для всех потоков. Потокам нужно только прочитать значение, а не писать ему. Я не могу явно указать приложению использовать постоянный кеш (например, cudaMemcpyToSymbol), потому что я использую библиотеку памяти, которая не дает мне явного элемента управления низкого уровня.Совместный доступ к широковещательному доступу к глобальной ячейке памяти на GPU

Мне интересно, как эта трансляция проходит под капотом и как она может отличаться от обычной схемы доступа, в которой каждый поток обращается к уникальной глобальной ячейке памяти (для простоты предполагают, что эта «обычная» схема доступа объединяется). Меня особенно интересуют любые неявные сериализации, которые могут иметь место в широковещательном случае, и как это может зависеть от разных архитектур.

Например, для Fermi, предположительно, первый поток для доступа к значению вытащит его в кэш L2, а затем к его кешу L1 SM, после чего каждый поток, находящийся на SM, попытается захватить его из L1 кэш. Есть ли какой-либо штраф за сериализацию, когда все потоки пытаются получить доступ к одному и тому же значению кеша L1?

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

Кроме того, раздел кемпинга беспокоит?

Я нашел еще один couple из questions, который адресовал аналогичную тему, но не на уровне детализации, достаточном для удовлетворения моего любопытства.

Заранее благодарен!

ответ

1

У меня есть приложение, в котором мне нужно транслировать одно (не постоянное, просто старое) значение в глобальной памяти для всех потоков. Потокам нужно только прочитать значение, а не писать ему.

Как в стороне, это в значительной степени определение постоянных данных, поскольку оно относится к использованию ядра CUDA. Возможно, вы не сможете воспользоваться им, но такой доступ называется «единообразным» доступом, и если есть повторный доступ такого типа, для значения, которое только обращается к, и не записывать, затем __constant__ Память - возможная оптимизация, которая может быть рассмотрена.

Мне интересно, как это вещание происходит под капотом

Чтобы быть ясно, вещания и/или сериализации должно быть возможно только тогда, когда потоки в то же перекос имеют доступ к конкретный элемент данных. Эти условия не применяются, когда потоки в разных искажениях получают доступ к одному и тому же местоположению; они будут обслуживаться отдельными запросами чтения warp.

Есть ли какой-либо штраф за сериализацию, когда все потоки пытаются получить доступ к одному и тому же значению кеша L1?

Не существует штрафа за сериализацию.Нити в одном и том же варпе могут быть read the same location without additional cost; все потоки, считываемые из одного и того же местоположения, будут обслуживаться в одном и том же цикле («трансляция»). Потоки отдельных перекосов, считывающих одно и то же местоположение на Ферми, будут обслуживаться отдельными запросами на чтение так же, как и ожидалось бы для любой команды, выполняемой отдельными перекосами. В этом случае нет никакой дополнительной или необычной стоимости.

Есть ли какой-либо штраф за сериализацию, когда все потоки пытаются получить одно и то же значение в L2?

same statements для L1 выше применимо к L2 в этом случае.

Кроме того, раздел кемпинга вызывает беспокойство?

Разделение кемпинга не имеет ничего общего со значениями, которые извлекаются из кеша L1 или L2. Перемещение кемпинга обычно относится к шаблону доступа к данным, который приводит к запросам DRAM, которые непропорционально обрабатываются одним из разделов на графическом процессоре, который имеет несколько разделов памяти. Для одного места, которое считывается несколькими потоками/искажениями, кэши будут обслуживать это. В лучшем случае необходима одна транзакция DRAM для обслуживания всех запросов, которые достаточно близки друг к другу во времени (т. Е. Игнорируют возможность обхода кеша), нацеливая одно местоположение.

+0

Привет, Роберт, Большое спасибо за ваш ответ. Я бы использовал память __constant__, если бы мог, но, к сожалению, в этом случае я не могу контролировать это. –

+0

Понял. Я упомянул об этом на благо других читателей. –

+0

Это поднимает еще один момент любопытства в моем сознании, если вы потакаете мне: предположим, что у каждого SM есть то же значение, что и в кеше L1. Предположим, что поток на одном SM теперь записывается в это значение. Согласно [этой слайде 39] (http://on-demand.gputechconf.com/gtc/2013/presentations/S3466-Programming-Guidelines-GPU-Architecture.pdf), которая приведет к аннулированию соответствующей строки кэша в L1, и записать в соответствующую строку кэша в L2. Мой вопрос: делает ли это также недействительным значение, хранящееся в кеше L1 другими SM? –