2013-09-01 2 views
1

Я только что спросил себя, если сложные вычисления индекса, например. threadIdx.x влияют на производительность. Постоянны ли эти переменные, как только ядро ​​загружается на устройство?Учет сложных индексов индекса влияет на производительность?

Я хочу перейти к огромному массиву, где индекс зависит от threadIdx.x, threadIdx.y и threadIdx.z. Мне нужно, например, по модулю операции, такие как

array[threadIdx.y % 2 + ...] 
+0

каждый расчет оказывает влияние, и есть общедоступная информация о том, сколько циклов каждый расчет и каждое чтение или запись нуждаются. Что касается доступа к встроенным переменным, таким как 'threadIdx', они могут рассматриваться как постоянные, насколько я знаю. Если вы выполняете повторяющиеся вычисления, просто сохраняйте эти вычисления в регистре или доверяйте своему компилятору и проверяйте свою сборку и использование gpu ressource вашего ядра (в случае, если у вас достаточно регистров, чтобы ваши параллельные блоки на см не уменьшались). Я предпочитаю писать чистый оптимизированный код, доверяя вашему компилятору. – djmj

ответ

0

Если кому-то интересно, я проверил соответствующий код PTX.

(1) Сложные вычисления идентификаторов потоков влияют на производительность. «threadIdx.x» и т. д. не являются константами.

(2) «threadIdx.y% 2» эффективно реализован и соответствует «threadIdx.y & 0x00000001» (Cuda Toolkit 5.5).

2

Я предполагаю, что

array[threadIdx.y % 2 + ...] 

это всего лишь пример.

Вообще говоря, операции % могут быть медленными. Полезный трюк, чтобы ускорить вычисление индекса будет отметить, что

foo%n==foo&(n-1) if n is a power of 2 

Таким образом, возможно, для примера выше компилятора сделает эту оптимизацию для вас, но в случае, если у вас есть foo%n, выше трюк стоит использовать.

3

У вас есть добавление и модуль в вычислении индекса.

Из руководства по программированию CUDA: пропускная способность operator+ очень высокая (160 для графического процессора, рассчитанного на 3,5 компьютера).

operator% требует десятков операций с пропускной способностью, аналогичной operator+.

В вашем случае вы используете operator% с постоянной константой, и компилятор, скорее всего, оптимизирует ее. Также ваша константа - это сила двух чисел (2), поэтому компилятор заменит ее поразрядным operator& (такая же пропускная способность, как operator+).

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