在C中将代码从SSE2转换为SSE4

时间:2015-08-20 06:02:40

标签: c++ sse simd

我必须将矢量优化C代码从sse2转换为sse4。我正在使用带有Ubuntu 14.1和gcc内置编译器的x86_64机器。我该怎么做呢?

编辑1:这是我试图使用SSE 4 C内在函数修改的代码的存根。使用SSE 4方法对代码进行的任何更改都将非常有帮助

    void pLayer(word *X, word *Y) {
      X[ 0] = Y[ 0],  X[ 1] = Y[ 4],  X[ 2] = Y[ 8],  X[ 3] = Y[12];
      X[ 4] = Y[16],  X[ 5] = Y[20],  X[ 6] = Y[24],  X[ 7] = Y[28];
      X[ 8] = Y[32],  X[ 9] = Y[36],  X[10] = Y[40],  X[11] = Y[44];
      X[12] = Y[48],  X[13] = Y[52],  X[14] = Y[56],  X[15] = Y[60];
      X[16] = Y[ 1],  X[17] = Y[ 5],  X[18] = Y[ 9],  X[19] = Y[13];
      X[20] = Y[17],  X[21] = Y[21],  X[22] = Y[25],  X[23] = Y[29];
      X[24] = Y[33],  X[25] = Y[37],  X[26] = Y[41],  X[27] = Y[45];
      X[28] = Y[49],  X[29] = Y[53],  X[30] = Y[57],  X[31] = Y[61];
      X[32] = Y[ 2],  X[33] = Y[ 6],  X[34] = Y[10],  X[35] = Y[14];
      X[36] = Y[18],  X[37] = Y[22],  X[38] = Y[26],  X[39] = Y[30];
      X[40] = Y[34],  X[41] = Y[38],  X[42] = Y[42],  X[43] = Y[46];
      X[44] = Y[50],  X[45] = Y[54],  X[46] = Y[58],  X[47] = Y[62];
      X[48] = Y[ 3],  X[49] = Y[ 7],  X[50] = Y[11],  X[51] = Y[15];
      X[52] = Y[19],  X[53] = Y[23],  X[54] = Y[27],  X[55] = Y[31];
      X[56] = Y[35],  X[57] = Y[39],  X[58] = Y[43],  X[59] = Y[47];
      X[60] = Y[51],  X[61] = Y[55],  X[62] = Y[59],  X[63] = Y[63];
    }

    void encrypt(word *X, const word *subkeys, const size_t nr) {
      static word Y[Bs];
      for(size_t i=0; i<nr;i++) {
        addRoundKey(X, subkeys + (i*Bs));
        sBoxLayer(Y, X);
        pLayer(X, Y);
      }
      addRoundKey(X, subkeys + (nr*Bs));
    }


    void rotate(word *k) {
      word temp[Ks];
      memcpy(temp,k,Ks*sizeof(word));
      for(size_t i =0; i<Ks; i++) {
        k[i] = temp[(i+61)%Ks];
      }
    }
void addRoundKey(word *X, const word *K) {
  //unsigned long long a,b,c,d;
  //a=X[0],b=K[0],c=X[1],d=K[1];
  /*var=_mm_xor_si128 (_mm_set_epi64x(X[0],X[1]),_mm_set_epi64x(K[0],K[1]));
  unsigned long long *v64val = (int64_t*) &var;
  X[0]=v64val[1],X[1] =v64val[0];*/
  //printf("here %llu %llu %llu \n %llu %llu %llu\n",a,b,c,d,v64val[0],v64val[1]);
  //X[0]= X[0]^K[0];  X[1] = X[1]^K[1];
  //printf("here %llu %llu\n",X[0],X[1]);
  //usleep(10000*1000);
  XOR_word(X[0],X[1],K[0],K[1]);
  //X[ 2] ^= K[ 2],  X[ 3] ^= K[ 3];
  XOR_word(X[2],X[3],K[2],K[3]);
  //X[ 4] ^= K[ 4],  X[ 5] ^= K[ 5];  
  XOR_word(X[4],X[5],K[4],K[5]);
  //X[ 6] ^= K[ 6],  X[ 7] ^= K[ 7];
  XOR_word(X[6],X[7],K[6],K[7]);
  //X[ 8] ^= K[ 8],  X[ 9] ^= K[ 9];
  XOR_word(X[8],X[9],K[8],K[9]);  
  //X[10] ^= K[10],  X[11] ^= K[11];
  XOR_word(X[10],X[11],K[10],K[11]);
  //X[12] ^= K[12],  X[13] ^= K[13];  
  XOR_word(X[12],X[13],K[12],K[13]);
  //X[14] ^= K[14],  X[15] ^= K[15];
  XOR_word(X[14],X[15],K[14],K[15]);
  //X[16] ^= K[16],  X[17] ^= K[17];  
  XOR_word(X[16],X[17],K[16],K[17]);
  //X[18] ^= K[18],  X[19] ^= K[19];
  XOR_word(X[18],X[19],K[18],K[19]);
  //X[20] ^= K[20],  X[21] ^= K[21];  
  XOR_word(X[20],X[21],K[20],K[21]);
  //X[22] ^= K[22],  X[23] ^= K[23];
  XOR_word(X[22],X[23],K[22],K[23]);
  //X[24] ^= K[24],  X[25] ^= K[25];  
  XOR_word(X[24],X[25],K[24],K[25]);
  //X[26] ^= K[26],  X[27] ^= K[27];
  XOR_word(X[26],X[27],K[26],K[27]);
  //X[28] ^= K[28],  X[29] ^= K[29];  
  XOR_word(X[28],X[29],K[28],K[29]);
  //X[30] ^= K[30],  X[31] ^= K[31];
  XOR_word(X[30],X[31],K[30],K[31]);
  //X[32] ^= K[32],  X[33] ^= K[33];  
  XOR_word(X[32],X[33],K[32],K[33]);
  //X[34] ^= K[34],  X[35] ^= K[35];
  XOR_word(X[34],X[35],K[34],K[35]);
  //X[36] ^= K[36],  X[37] ^= K[37];  
  XOR_word(X[36],X[37],K[36],K[37]);
  //X[38] ^= K[38],  X[39] ^= K[39];
  XOR_word(X[38],X[39],K[38],K[39]);
  //X[40] ^= K[40],  X[41] ^= K[41];  
  XOR_word(X[40],X[41],K[40],K[41]);
  //X[42] ^= K[42],  X[43] ^= K[43];
  XOR_word(X[42],X[43],K[42],K[43]);
  //X[44] ^= K[44],  X[45] ^= K[45];  
  XOR_word(X[44],X[45],K[44],K[45]);
  //X[46] ^= K[46],  X[47] ^= K[47];
  XOR_word(X[46],X[47],K[46],K[47]);
  //X[48] ^= K[48],  X[49] ^= K[49];  
  XOR_word(X[48],X[49],K[48],K[49]);
  //X[50] ^= K[50],  X[51] ^= K[51];
  XOR_word(X[50],X[51],K[50],K[51]);
  //X[52] ^= K[52],  X[53] ^= K[53];  
  XOR_word(X[52],X[53],K[52],K[53]);
  //X[54] ^= K[54],  X[55] ^= K[55];
  XOR_word(X[54],X[55],K[54],K[55]);
  //X[56] ^= K[56],  X[57] ^= K[57];  
  XOR_word(X[56],X[57],K[56],K[57]);
  //X[58] ^= K[58],  X[59] ^= K[59];
  XOR_word(X[58],X[59],K[58],K[59]);
  //X[60] ^= K[60],  X[61] ^= K[61];  
  XOR_word(X[60],X[61],K[60],K[61]);
  //X[62] ^= K[62],  X[63] ^= K[63];
  XOR_word(X[63],X[63],K[63],K[63]);
}

void addRoundKey(word *X, const word *K) {
  //unsigned long long a,b,c,d;
  //a=X[0],b=K[0],c=X[1],d=K[1];
  /*var=_mm_xor_si128 (_mm_set_epi64x(X[0],X[1]),_mm_set_epi64x(K[0],K[1]));
  unsigned long long *v64val = (int64_t*) &var;
  X[0]=v64val[1],X[1] =v64val[0];*/
  //printf("here %llu %llu %llu \n %llu %llu %llu\n",a,b,c,d,v64val[0],v64val[1]);
  //X[0]= X[0]^K[0];  X[1] = X[1]^K[1];
  //printf("here %llu %llu\n",X[0],X[1]);
  //usleep(10000*1000);
  XOR_word(X[0],X[1],K[0],K[1]);
  //X[ 2] ^= K[ 2],  X[ 3] ^= K[ 3];
  XOR_word(X[2],X[3],K[2],K[3]);
  //X[ 4] ^= K[ 4],  X[ 5] ^= K[ 5];  
  XOR_word(X[4],X[5],K[4],K[5]);
  //X[ 6] ^= K[ 6],  X[ 7] ^= K[ 7];
  XOR_word(X[6],X[7],K[6],K[7]);
  //X[ 8] ^= K[ 8],  X[ 9] ^= K[ 9];
  XOR_word(X[8],X[9],K[8],K[9]);  
  //X[10] ^= K[10],  X[11] ^= K[11];
  XOR_word(X[10],X[11],K[10],K[11]);
  //X[12] ^= K[12],  X[13] ^= K[13];  
  XOR_word(X[12],X[13],K[12],K[13]);
  //X[14] ^= K[14],  X[15] ^= K[15];
  XOR_word(X[14],X[15],K[14],K[15]);
  //X[16] ^= K[16],  X[17] ^= K[17];  
  XOR_word(X[16],X[17],K[16],K[17]);
  //X[18] ^= K[18],  X[19] ^= K[19];
  XOR_word(X[18],X[19],K[18],K[19]);
  //X[20] ^= K[20],  X[21] ^= K[21];  
  XOR_word(X[20],X[21],K[20],K[21]);
  //X[22] ^= K[22],  X[23] ^= K[23];
  XOR_word(X[22],X[23],K[22],K[23]);
  //X[24] ^= K[24],  X[25] ^= K[25];  
  XOR_word(X[24],X[25],K[24],K[25]);
  //X[26] ^= K[26],  X[27] ^= K[27];
  XOR_word(X[26],X[27],K[26],K[27]);
  //X[28] ^= K[28],  X[29] ^= K[29];  
  XOR_word(X[28],X[29],K[28],K[29]);
  //X[30] ^= K[30],  X[31] ^= K[31];
  XOR_word(X[30],X[31],K[30],K[31]);
  //X[32] ^= K[32],  X[33] ^= K[33];  
  XOR_word(X[32],X[33],K[32],K[33]);
  //X[34] ^= K[34],  X[35] ^= K[35];
  XOR_word(X[34],X[35],K[34],K[35]);
  //X[36] ^= K[36],  X[37] ^= K[37];  
  XOR_word(X[36],X[37],K[36],K[37]);
  //X[38] ^= K[38],  X[39] ^= K[39];
  XOR_word(X[38],X[39],K[38],K[39]);
  //X[40] ^= K[40],  X[41] ^= K[41];  
  XOR_word(X[40],X[41],K[40],K[41]);
  //X[42] ^= K[42],  X[43] ^= K[43];
  XOR_word(X[42],X[43],K[42],K[43]);
  //X[44] ^= K[44],  X[45] ^= K[45];  
  XOR_word(X[44],X[45],K[44],K[45]);
  //X[46] ^= K[46],  X[47] ^= K[47];
  XOR_word(X[46],X[47],K[46],K[47]);
  //X[48] ^= K[48],  X[49] ^= K[49];  
  XOR_word(X[48],X[49],K[48],K[49]);
  //X[50] ^= K[50],  X[51] ^= K[51];
  XOR_word(X[50],X[51],K[50],K[51]);
  //X[52] ^= K[52],  X[53] ^= K[53];  
  XOR_word(X[52],X[53],K[52],K[53]);
  //X[54] ^= K[54],  X[55] ^= K[55];
  XOR_word(X[54],X[55],K[54],K[55]);
  //X[56] ^= K[56],  X[57] ^= K[57];  
  XOR_word(X[56],X[57],K[56],K[57]);
  //X[58] ^= K[58],  X[59] ^= K[59];
  XOR_word(X[58],X[59],K[58],K[59]);
  //X[60] ^= K[60],  X[61] ^= K[61];  
  XOR_word(X[60],X[61],K[60],K[61]);
  //X[62] ^= K[62],  X[63] ^= K[63];
  XOR_word(X[63],X[63],K[63],K[63]);
}

1 个答案:

答案 0 :(得分:3)

SSE4.1相比,SSE3(以及SSSE3SSE2)中有一些新的SIMD说明。这些新操作可能会提高代码的性能。 但我无法推荐任何具体的内容,因为我看不到您的代码。 从SSE2到SSSE3有一些优化的例子(这是我的项目):

http://simd.sourceforge.net/