SIMD добавление от разбросанных данных к разбросанным данным - PullRequest
0 голосов
/ 02 мая 2020

Есть ли способ вернуть инструкцию добавления simd непосредственно в местоположения разбросанных данных?

Пример кода:

#include <intrin.h>

__declspec(align(256)) union quad_double{
  double d[4];
  __m256d m;
}

void simd_add_to(double& in0, double& in1, double& in2, double& in3,
                  double val0, double val1, double val2, double val3) {

  quad_double source = {in0, in1, in2, in3}; 
  quad_double val = {val0, val2, val2, val3};
  quad_double res;

  res.m = _mm256_add_pd(source.m, val.m);  //doesn't write the values to in0, in1, in2, in3

  //slow... 
  in0 = res.d[0];
  in1 = res.d[1];
  in2 = res.d[2];
  in3 = res.d[3];
}

int main(){
  double x0 = 0;
  double x1 = 0;
  double x2 = 0;
  double x3 = 0;

  simd_add_to(x0,x1,x2,x3,0.5,1.5,2.5,3.5);

  return 0;
}

Если я правильно понимаю, инструкция simd выполняется посредством трех операций :

1) вектор источника нагрузки 2) вектор значения нагрузки 3) сложение вычислений 4) возвращаемое значение

Четвертый шаг всегда возвращает вектор simd, есть ли способ вернуть результат непосредственно в разбросанные источники? и если нет, могу ли я как-нибудь ускорить передачу на входы (in0, in1, ...)?

Edit 1: Редизайн с выровненными источниками и рассеянными целями:

#include <intrin.h>

void simd_add_to(double& in0, double& in1, double& in2, double& in3, double* val) {
  __m256d source = _mm256_set_pd(in3, in2, in1, in0); 
  __m256d m_val = _mm256_loadu_pd(val);

  auto res = _mm256_add_pd(source, m_val);  

  //slow... 
  in0 = res.d[0];
  in0 = res.d[1];
  in0 = res.d[2];
  in0 = res.d[3];
}


int main(){

  //pseudo code! :  

  unsigned c = 0;
  double sources[n] = {1,2,3...,n};

  while(not_done){
    target0 = get_target_ref();
    target1 = get_target_ref();
    target2 = get_target_ref();
    target3 = get_target_ref();
    target4 = get_target_ref();
    target5 = get_target_ref();
    target6 = get_target_ref();
    target7 = get_target_ref();
    simd_add_to(target0,target1,target2,target3, &sources[c]);
    simd_add_to(target4,target5,target6,target7, &sources[c+4]);  
    c+=8;
  }

  return 0;
}

Есть ли способ ускорить возврат вычисленных данных в таргертс (разбросано)?

...