Избегайте расхождения деформации

У меня есть логический 1D массив T[N] управление величиной смены осуществляется следующим образом:

**a: массив указателей на n*n матрицы в глобальной памяти я хочу для каждой матрицы a Для подстановки сдвига * Идентичность получить:

a=a-shift*eye(n)

Я имею:

__device__ bool T[N];
__device__ float shift1[N];
__device__ float shift2[N];
__device__ float* a[N];

Значение сдвига контролируется T, если T[i]==true => shift=shift1, иначе shift=shift2;

int tid=threadIdx.x;

      if(tid < N){

              if(T[tid]){

               for (int i=0;i<n;i++){

                   a[tid][i*n+i]=a[tid][i*n+i]-shift1[tid];
               }

            }
        else {

          for (int i=0;i<n;i++){

                   a[tid][i*n+i]=a[tid][i*n+i]-shift2[tid];
               }
            }
        }
      __syncthreads();

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

1 ответ

Решение

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

int tid=threadIdx.x;
  float myshift;
  if (T[tid]) myshift = shift1[tid];
  else myshift = shift2[tid];
  if(tid < N){
           for (int i=0;i<n;i++){

               a[tid][i*n+i]=a[tid][i*n+i]-myshift;
           }

        }
  __syncthreads();

Компилятор будет определять загрузку myshift (создание "условной нагрузки" уже упоминалось). Это предопределение сводит к минимуму стоимость расхождения для самой нагрузки. Остальная часть этого кода при этом преобразовании не расходится (за исключением случаев, когда tid >= N, что должно быть не беспокойство).

Опять же, как уже упоминалось, все это преобразование может уже наблюдаться и выполняться компилятором. Это возможно, но не может быть подтверждено без выполнения действительного полного контрольного примера, который вы не предоставили.

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

Другие вопросы по тегам