Почему нет конфликтов банков в глобальной памяти для Cuda/OpenCL?

Одна вещь, которую я не понял, и Google мне не помогает, почему возможны конфликты банков с общей памятью, но не с глобальной памятью? Могут ли быть конфликты банка с реестрами?

ОБНОВЛЕНИЕ Вау, я очень ценю два ответа от Тиббита и Гризли. Кажется, я могу поставить зеленую галочку только на один ответ. Я новичок в переполнении стека. Думаю, мне нужно выбрать один ответ как лучший. Могу ли я сделать что-нибудь, чтобы поблагодарить за ответ, которому я не даю зеленый чек?


person smuggledPancakes    schedule 01.10.2010    source источник
comment
Вы всегда можете проголосовать за любой вопрос или ответ, который вам нравится   -  person Grizzly    schedule 04.10.2010
comment
Конфликты банков могут возникать на других уровнях иерархии памяти, а также в файле регистров. Конфликты общих банков памяти могут существенно повлиять на производительность ядра и полностью контролируются разработчиком. Другие типы конфликтов с банками оказывают меньшее влияние на производительность и не могут быть разрешены разработчиком, поэтому они не сообщаются разработчику.   -  person Greg Smith    schedule 28.11.2012


Ответы (3)


Короткий ответ: Нет конфликтов банков ни в глобальной памяти, ни в регистрах.

Пояснение:

Ключом к пониманию причин является понимание детализации операций. Один поток не обращается к глобальной памяти. Доступ к глобальной памяти "объединяется". Поскольку глобальная память очень медленная, любой доступ потоков внутри блока группируется вместе, чтобы сделать как можно меньше запросов к глобальной памяти.

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

Доступ к регистрам не может получить ни один поток, кроме того, которому он выделен. Поскольку вы не можете читать или писать в мои регистры, вы не можете заблокировать мне доступ к ним — следовательно, нет никаких банковских конфликтов.

Кто может читать и записывать в глобальную память?

Only blocks. Один поток может сделать доступ, но транзакция будет обрабатываться на уровне блока (на самом деле уровень деформации/половины деформации, но я пытаюсь не усложнять). Если два блока обращаются к одной и той же памяти, я не думаю, что это займет больше времени, и это может произойти за счет кэша L1 в новейших устройствах, хотя это не очевидно.

Кто может читать и записывать в общую память?

Any thread within a given block. Если у вас есть только 1 поток на блок, у вас не может быть конфликта банков, но у вас не будет приемлемой производительности. Конфликты банков возникают из-за того, что блок выделен нескольким, скажем, 512 потокам, и все они борются за разные адреса в одном банке (не совсем один и тот же адрес). В конце Руководства по программированию CUDA C есть отличные изображения этих конфликтов — рисунок G2, на странице 167 (фактически страница 177 в pdf). Ссылка на версию 3.2

Кто может читать и писать в регистры?

Only the specific thread to which it is allocated. Следовательно, одновременно к нему обращается только один поток.

person M. Tibbits    schedule 02.10.2010
comment
Обратите внимание, что мой комментарий о кеше L1 на самом деле является моим собственным вопросом - возникают ли конфликты банков в кеше L1. Поскольку это полностью обрабатывается аппаратно, я не думаю, что нам сказали об этом в последней документации. (Но L1 есть только в новейшем аппаратном обеспечении 2. *, поэтому, если у вас нет графического процессора Fermi, этот момент отключен). - person M. Tibbits; 02.10.2010

Могут ли быть конфликты банков для данного типа памяти, очевидно, зависит от структуры памяти и, следовательно, от ее назначения.

Так почему же общая память спроектирована таким образом, что допускает конфликты банков?

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

Что насчет регистров?

Регистры предназначены для доступа в качестве операндов для инструкций ALU, что означает, что доступ к ним должен осуществляться с очень малой задержкой. Поэтому они получают больше транзисторов на бит, чтобы сделать это возможным. Я не уверен, как именно осуществляется доступ к регистрам в современных процессорах (не та информация, которая вам нужна часто, и ее не так просто найти). Однако, очевидно, было бы крайне непрактично организовывать регистры в банки (для более простых архитектур вы обычно видите, что все регистры висят на одном большом мультиплексоре). Так что нет, конфликтов с банками из-за реестров не будет.

Глобальная память

Во-первых, глобальная память работает с другой степенью детализации, чем разделяемая память. Доступ к памяти осуществляется блоками по 32, 64 или 128 байт (по крайней мере, для GT200, для fermi всегда 128 байт, но кэшируется, у AMD немного по-другому), где каждый раз, когда вы хотите что-то из блока, осуществляется доступ/передача всего блока. Вот почему вам нужен объединенный доступ, поскольку, если каждый поток обращается к памяти из другого блока, вам придется передавать все блоки.

Но кто сказал, что банковских конфликтов не бывает? Я не совсем уверен в этом, потому что я не нашел никаких фактических источников, подтверждающих это для оборудования NVIDIA, но это кажется логичным: глобальная память обычно распределяется между несколькими микросхемами оперативной памяти (что можно легко проверить, посмотрев на видеокарта). Было бы разумно, если бы каждый из этих чипов был чем-то вроде банка локальной памяти, поэтому вы могли бы получить конфликты банков, если есть несколько одновременных запросов к одному и тому же банку. Однако для одной вещи эффект будет гораздо менее выраженным (поскольку большая часть времени, затрачиваемого на доступ к памяти, в любом случае является задержкой для получения данных из A в B), и это не будет заметным эффектом «внутри» одной рабочей группы. (поскольку одновременно выполняется только один халфварп, и если этот халфварп выдает более одного запроса, у вас есть необъединенный доступ к памяти, поэтому вы уже получаете удар, что затрудняет измерение последствий этого конфликта. Таким образом, вы получите конфликты, только если несколько рабочих групп пытаются получить доступ к одному и тому же банку.В вашей типичной ситуации для gpgpu у вас есть большой набор данных, лежащий в последовательной памяти, поэтому эффекты на самом деле не должны быть заметны, поскольку есть достаточно других рабочих групп, обращающихся к другим банкам в то же время, но это Должна быть возможна ситуация, когда набор данных сосредоточен всего в нескольких банках, что приведет к удару по пропускной способности (поскольку максимальная пропускная способность будет получена при равном распределении доступа по всем банкам, поэтому каждый банк будет имеют лишь часть этой пропускной способности). Опять же, я не читал ничего, чтобы доказать эту теорию для оборудования nvidia (в основном все сосредоточено на объединении, что, конечно, более важно, поскольку делает это не проблемой для естественных наборов данных). Однако, согласно руководству по вычислениям ATI Stream, это ситуация для карт Radeon (для 5xxx: банки находятся на расстоянии 2 КБ друг от друга, и вы хотите убедиться, что вы распределяете свои доступы (имеется в виду от всех симуляционно активных рабочих групп) одинаково по всем банкам), поэтому я можно предположить, что карты NVidia ведут себя аналогично.

Конечно, для большинства сценариев возможность конфликтов банков в глобальной памяти не является проблемой, поэтому на практике вы можете сказать:

  • Следите за объединением при доступе к глобальной памяти
  • Следите за конфликтами банков при доступе к локальной памяти
  • Нет проблем с доступом к регистрам
person Grizzly    schedule 02.10.2010
comment
Также следите за размещением разделов в глобальной памяти! - person mch; 07.10.2010
comment
В поисках информации о кемпинге разделов я наткнулся на этот ответ. Вы правы, глобальная память физически разделена на разделы, и некоторые шаблоны доступа могут генерировать конфликты даже при объединении доступов (см. документацию о примере транспонирования матрицы в CUDA SDK). Однако в архитектурах Fermi и в целом для устройств с вычислительными возможностями 2.x доступ к глобальной памяти кэшируется, имеет ширину 32 байта, а адреса хэшируются, поэтому теоретически разбиение на разделы не должно быть проблемой. - person Auron; 18.07.2012
comment
Снижают ли эти улучшения в архитектуре памяти вычислительные возможности ›=2.0 влияние кемпинга разделов на записи глобальной памяти? - person Ahmed Fasih; 07.12.2012
comment
В примере с транспонированием матрицы CUDA 5 разбиение на разделы, по-видимому, не влияет на C2050 Tesla (вычислительные возможности 2.0), поскольку между грубым и мелкозернистым псевдотранспонированием едва ли есть какая-либо разница. Но мне нужно официальное подтверждение. - person Ahmed Fasih; 07.12.2012
comment
Есть ли официальная документация о хешировании адресов в архитектурах Fermi? - person Benedikt Waldvogel; 23.04.2013
comment
Что касается доступа к глобальной памяти в 32-, 64- или 128-битных фрагментах, есть ли разница в эффективности между потоками, обращающимися к последовательным 8-битным (char) фрагментам и последовательным 32-битным (int) фрагментам? - person Andreas Yankopolus; 14.11.2016
comment
@Auron Где вы прочитали, что адреса хэшируются в графических процессорах Nvidia. Мне бы очень помогло, если бы вы могли указать мне на источник этого утверждения. - person Saksham Jain; 02.06.2018
comment
@SakshamJain Извините. Это было 5 лет назад, и я боюсь, что не могу вспомнить. Возможно, это было в документации CUDA, но точно сказать не могу. - person Auron; 06.06.2018
comment
и если этот полуварп выдает более одного запроса, у вас есть несвязанный доступ к памяти. Я полагаю, вы имели в виду слились вместо этого? - person gallickgunner; 27.06.2018

несколько потоков, обращающихся к одному и тому же банку, не обязательно означают наличие конфликта банков. Возникает конфликт, если потоки хотят одновременно читать из ДРУГОЙ СТРОКИ в одном и том же банке.

person Paulus    schedule 13.02.2011