tile_static динамически индексируемые массивы; я должен даже беспокоиться?

Я собираюсь изо всех сил, чтобы попытаться сохранить часто используемые данные в tile_static память, чтобы воспользоваться преимуществами безграничной нирваны производительности, которая последует.

Однако я только что прочитал, что только некоторые аппаратные средства / драйверы могут на самом деле динамически индексировать массивы tile_static, и что операция в любом случае может просто перетекать в глобальную память.

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

tile_static int staticArray[128];
int resultFast = staticArray[0]; // this is super fast

// but what about this:
i = // dynamically derived value!
int resultNotSoFast = staticArray[i]; // is this faster than getting it from global memory?

Как я могу узнать, поддерживает ли мой GPU / драйвер динамическое индексирование статических массивов?

2

Решение

Динамическая индексация локальной памяти

Поэтому я немного покопался в этом, потому что тоже хотел это понять.
Если вы имеете в виду динамическое индексирование локальной памяти, не tile_static (или на языке CUDA «общая память»). В вашем примере выше staticArray должен быть объявлен как:

int staticArray[128]; // not tile_static

Это не может быть динамически проиндексировано, потому что массив int staticArray[128] фактически хранится как 128 регистров, и к ним нельзя получить динамический доступ. Выделение таких больших массивов в любом случае проблематично, так как использует большое количество регистров, которые являются ограниченным ресурсом на GPU. Используйте слишком много регистров на поток, и ваше приложение не сможет использовать весь доступный параллелизм, потому что некоторые доступные потоки будут остановлены, ожидая, когда регистры станут доступными.

В случае с C ++ AMP я даже не уверен, что уровень абстракции, предоставляемый DX11, может сделать это несколько нерелевантным. Мне не хватает эксперта по DX11, чтобы знать.

Здесь есть отличное объяснение, Как хранить массив в ядре CUDA? "локальная память потока"?

Банковские конфликты

Плитка статической памяти делится на несколько модулей, называемых
банки. Статическая память листов обычно состоит из 16, 32 или 64 банков,
каждый из которых имеет ширину 32 бита. Это специфично для конкретного графического процессора
аппаратное обеспечение и может измениться в будущем. Плитка статическая память есть
чередовал через эти банки. Это означает, что для графического процессора с плиткой
статическая память реализована с 32 банками, если arr является массивом < float, 1>, затем arr [1] и arr [33] находятся в одном и том же банке, потому что каждый float занимает одно 32-битное местоположение банка. Это ключевой момент
понять, когда дело доходит до урегулирования банковских конфликтов.

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

Я думаю, что ключевым моментом путаницы может быть (на основе некоторых других ваших вопросов) то, что банк памяти имеет ширину 32 бита, но отвечает за доступ ко всей памяти в банке, которая будет 1/16, 1/32 или 1/64 от общей статической памяти тайлов.

Вы можете прочитать больше о банковских конфликтах здесь Что такое банковский конфликт? (Занимаюсь программированием на Cuda / OpenCL)

2

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

Других решений пока нет …

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