2013-05-30 3 views
1

У меня есть массив 2D-хозяев с 10 строками и 96 столбцами. Я загружаю этот массив в свою глобальную память устройства cuda линейно, т. Е. Row1, row2, row3 ... row10.CUDA 5.0 Выравнивание памяти и объединенный доступ

Массив типа float. В моем ядре каждый поток обращается к одному значению float из глобальной памяти устройства.

The BLOCK_SIZE I use is = 96 
The GRID_DIM I use is = 10 

Теперь то, что я понял из «Cuda C руководства по программированию» для слившихся доступов, шаблон я использую правильно, доступ последовательно ячейки памяти с помощью перекоса. Но есть пункт о размещении памяти по 128 байт памяти. Который я не понимаю.

Q1) 128-битная настройка памяти; Означает ли это, что каждый поток в warp должен получить доступ к 4 байтам, начиная с адреса 0x00 (например) до 0x80?

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

Мое понимание: один поток должен сделать один доступ к памяти с должно быть 4 байта, от диапазона адреса, например от 0x00 до 0x80. Если поток из warp получает доступ к местоположению за его пределами, его неэкранированный доступ.

ответ

8

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

Если 32 потока в вашей деформации каждый считывают поплавок, вы будете читать в общей сложности 128 байтов из глобальной памяти. Если память выровнена правильно, все чтения будут из одного блока. Если выравнивание выключено, вам понадобятся два чтения. Если вы делаете что-то вроде a[32*i], каждый доступ будет поступать из другого 128-байтового блока в глобальной памяти, что будет очень медленным.

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

Если у вас есть массив из 96 поплавков, то если каждая нить с индексом i в вашем warp обращается к a[i], это будет объединенное чтение. То же самое с a[i+32] или a[i+64].

Итак, ответ на вопрос Q1 заключается в том, что все потоки должны оставаться в пределах одного и того же блока длиной 128 байт, выровненных на 128 байтовых границах.

Ответ на ваш Q2 является то, что если ваши массивы выровнены правильно, и ваши доступы формы a[32*x+i] с i нить ид и x любое целое число, которое является одинаковым для всех потоков, ваши доступы будут соединялись.

В соответствии с разделом 5.3.2.1.1 руководства по программированию память всегда выровнена на границах не менее 256 байт, поэтому массивы, созданные с помощью cudaMalloc, всегда выравниваются правильно.

+0

Благодаря @Jeffrey. Он разъясняет все мои сомнения. – fahad

Смежные вопросы