Сколько памяти я могу объявить как tile_static?

В настоящее время я нахожусь в процессе написания моего кода C ++ AMP. Для каждой плитки у меня есть 4096 байтов данных, которые часто читаются, поэтому я хотел бы объявить это как tile_static. Делить это на несколько плиток нецелесообразно, поскольку каждому потоку необходим доступ ко всем данным. Мои тайлы состоят из 128 потоков, поэтому они должны занимать 2-4 деформации на графических процессорах Nvidia / AMD.

Я только что прочитал следующую статью, которая, кажется, предполагает, что я могу использовать только 1024 бита в tile_static для основы:
http://blogs.msdn.com/b/nativeconcurrency/archive/2012/08/14/avoid-bank-conflicts-on-tile-static-memory-with-c-amp.aspx

На некоторых современных графических процессорах память tile_static состоит из «n» одинакового размера
банки памяти, к которым можно обращаться одновременно и последовательно
«M» -битные слова отображаются в последовательных банках памяти. Точный
организация памяти tile_static (т.е. n и m) является аппаратной
зависимый. Например, на карте Nvidia GTX 580 или ATI HD 5870
карта памяти tile_static имеет 32 банка (n = 32), которые организованы таким
что последовательные 32-битные слова (m = 32) отображаются в последовательные банки памяти
.
Обратите внимание, что n может отличаться от оборудования к оборудованию, m обычно
32. В оставшейся части поста я буду считать, что m равно 32.

Означает ли это, что я могу объявить до 1024 бит на деформацию или на поток? Все переменные tile_static являются общими для деформаций или каждая деформация имеет свою собственную копию?

Сколько из этих вопросов зависит от аппаратного обеспечения, и если да, то как я могу узнать ограничения во время выполнения?

я прочитал обложка книги c ++ AMP для покрытия, и хотя я благодарен авторам за то, что они познакомили меня с предметом, он, похоже, не рассматривал этот вопрос (или, если это так, я его не понял).

В Интернете много информации о том, как использовать память tile_static (это хорошее начало: http://www.danielmoth.com/Blog/tilestatic-Tilebarrier-And-Tiled-Matrix-Multiplication-With-C-AMP.aspx) но никто, кажется, не говорит о том, сколько мы можем объявить, что делает невозможным фактически реализовать что-либо из этого! Эта последняя ссылка дает следующий пример:

01: void MatrixMultiplyTiled(vector<float>& vC,
const vector<float>& vA,
const vector<float>& vB, int M, int N, int W)
02: {
03:   static const int TS = 16;

04:   array_view<const float,2> a(M, W, vA);
05:   array_view<const float,2> b(W, N, vB);
06:   array_view<float,2> c(M,N,vC); c.discard_data();

07:   parallel_for_each(c.extent.tile< TS, TS >(),
08:   [=] (tiled_index< TS, TS> t_idx) restrict(amp)
09:   {
10:     int row = t_idx.local[0]; int col = t_idx.local[1];
11:     float sum = 0.0f;

12:     for (int i = 0; i < W; i += TS) {
13:        tile_static float locA[TS][TS], locB[TS][TS];
14:        locA[row][col] = a(t_idx.global[0], col + i);
15:        locB[row][col] = b(row + i, t_idx.global[1]);
16:        t_idx.barrier.wait();

17:        for (int k = 0; k < TS; k++)
18:          sum += locA[row][k] * locB[k][col];

19:        t_idx.barrier.wait();
20:     }

21:     c[t_idx.global] = sum;
22:   });
23: }

Обратите внимание, что строка 13 объявляет 2x 1024 бита, и я надеюсь, что мои 4096 бит не так уж и велики. Если кто-то, имеющий некоторый опыт в программировании на c ++ amp или GPU в целом, может мне помочь, это было бы здорово — Я полагаю, что эти вопросы больше зависят от аппаратного обеспечения / реализации, чем от самого расширения языка AMP …

2

Решение

Во-первых, я думаю, что вы имеете в виду 2 x 1024 байта, а не биты. Статическая память плитки объявляется для каждой плитки, а не для потока или деформации. Деформация на самом деле является просто структурой планирования для организации групп потоков, которые выполняются вместе, как правило, в группах по 32 или 64 в зависимости от архитектуры. Чтобы облегчить жизнь планировщику, вы должны использовать плитки, которые содержат количество потоков, которое является точным кратным размеру основы.

Прежде чем обсуждать это подробно, полезно снова посмотреть, как графические процессоры
выполнить потоки, составляющие ваше ядро. GPU состоят из нескольких
процессоры. AMD называет их вычислительными блоками, а NVIDIA называет их
их потоковые мультипроцессоры. Каждый график CU работает по частям или
пучки нитей, называемые перекосами. Когда деформация заблокирована,
Планировщик CU может скрывать задержки, переключаясь на другую деформацию
чем ожидание текущего перекоса. КС могут использовать этот подход
скрыть задержки, связанные с обращениями к памяти, при условии, что
достаточно перекосов.

Одна из причин того, что это не очень подробно описано в книге, заключается в том, что C ++ AMP разработан, чтобы быть независимым от аппаратного обеспечения и работает поверх DirectX. Поэтому, если вы разрабатываете свое приложение с учетом конкретных деталей графического процессора, оно может стать менее переносимым. Кроме того, поскольку C ++ AMP реализован поверх DX11, в некоторых случаях просто нет возможности получить информацию об аппаратном обеспечении. Размер основы, tile_static Размер памяти и размер кэша — все это примеры. Как и в случае с любой книгой, у нас также были ограничения по объему и срокам публикации.

Однако вы можете сделать разумные предположения о размере основы и памяти тайлов. На современном графическом процессоре предполагается, что размер деформации составляет 32 или 64, а статическая память тайлов порядка 10 с. Если вы действительно хотите настроить свой код для конкретного процессора, то вы можете использовать спецификации производителя и / или инструмент, который отображает соответствующую информацию.

На Tesla разделяемая память
16KB. На Fermi общая память на самом деле составляет 64 КБ и может быть
сконфигурированный как программно-управляемый кэш данных 48 КБ с аппаратным обеспечением 16 КБ
кэш данных или наоборот (16 КБ, 48 КБ, HW кэш).

10 с КБ могут показаться не слишком много памяти для tile_static массив, но в действительности есть другие давления, которые также будут определять размер плитки; давление реестра для одного. Вы также должны помнить, что несколько очень больших плиток обычно приводят к низкой загруженности и, следовательно, к неэффективному коду.

Я согласен, что вся терминология банка памяти сбивает с толку. 32 бита относится к размеру банка памяти, а не к размеру общей памяти. Вы можете рассматривать банк как механизм доступа, а не как общее хранилище. Как видно из приведенной выше ссылки, каждый 32-битный банк сопоставляется с последовательными 32-битными адресами памяти. Поскольку вы получаете один доступ к банку за цикл, самый эффективный способ получить доступ к памяти — это прочитать по одному элементу из каждого банка. Или, чтобы все темы читали один и тот же элемент (трансляцию). Книга содержит некоторое обсуждение этого в главе о производительности / оптимизации.

3

Другие решения

Это о 32kb. Если вы достигнете предела, вы получите ошибку при попытке компиляции.

Если вы не получили ошибку, все в порядке. Вы должны быть в состоянии проверить это самостоятельно, объявив массивный tile_static массив, и вы должны получить гневное сообщение о том, что tile_static предел

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector