Подтвердить что ты не робот

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

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

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

4b9b3361

Ответ 1

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

Объяснение:

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

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

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

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

Only blocks. Один поток может сделать доступ, но транзакция будет обрабатываться на уровне блока (на самом деле уровень warp/half warp, но я стараюсь не быть сложным). Если два блока обращаются к одной и той же памяти, я не думаю, что это займет больше времени, и это может ускориться кешем 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. Следовательно, только один поток обращается к нему за один раз.

Ответ 2

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

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

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

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

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

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

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

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

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

  • Следите за объединением при доступе к глобальной памяти
  • Следите за конфликтами в банках при доступе к локальной памяти
  • Нет проблем с доступом к регистрам

Ответ 3

несколько потоков, обращающихся к одному и тому же банку, не обязательно означают, что существует конфликт в банке. Существует конфликт, если потоки хотят читать одновременно с A DIFFERENT ROW в одном банке.