text: #include <stdio.h>
  #include <stdlib.h>
  #include <stdint.h>
  #include <string.h>
  #include <x86intrin.h>
  
  
  static void orthogonalize(__m256i data[]) {
  
    __m256i mask_l[8] = {
      _mm256_set1_epi64x(0xaaaaaaaaaaaaaaaaUL),
      _mm256_set1_epi64x(0xccccccccccccccccUL),
      _mm256_set1_epi64x(0xf0f0f0f0f0f0f0f0UL),
      _mm256_set1_epi64x(0xff00ff00ff00ff00UL),
      _mm256_set1_epi64x(0xffff0000ffff0000UL),
      _mm256_set1_epi64x(0xffffffff00000000UL),
      _mm256_set_epi64x(0UL,-1UL,0UL,-1UL),
      _mm256_set_epi64x(0UL,0UL,-1UL,-1UL),
    
    };
  
    __m256i mask_r[8] = {
      _mm256_set1_epi64x(0x5555555555555555UL),
      _mm256_set1_epi64x(0x3333333333333333UL),
      _mm256_set1_epi64x(0x0f0f0f0f0f0f0f0fUL),
      _mm256_set1_epi64x(0x00ff00ff00ff00ffUL),
      _mm256_set1_epi64x(0x0000ffff0000ffffUL),
      _mm256_set1_epi64x(0x00000000ffffffffUL),
      _mm256_set_epi64x(-1UL,0UL,-1UL,0UL),
      _mm256_set_epi64x(-1UL,-1UL,0UL,0UL),
    };
    
    for (int i = 0; i < 8; i ++) {
      int n = (1UL << i);
      for (int j = 0; j < 256; j += (2 * n))
        for (int k = 0; k < n; k ++) {
          __m256i u = _mm256_and_si256(data[j + k], mask_l[i]);
          __m256i v = _mm256_and_si256(data[j + k], mask_r[i]);
          __m256i x = _mm256_and_si256(data[j + n + k], mask_l[i]);
          __m256i y = _mm256_and_si256(data[j + n + k], mask_r[i]);
          if (i <= 5) {
            data[j + k] = _mm256_or_si256(u, _mm256_srli_epi64(x, n));
            data[j + n + k] = _mm256_or_si256(_mm256_slli_epi64(v, n), y);
          } else if (i == 6) {
            /* Note the "inversion" of srli and slli. */
            data[j + k] = _mm256_or_si256(u, _mm256_slli_si256(x, 8));
            data[j + n + k] = _mm256_or_si256(_mm256_srli_si256(v, 8), y);
          } else {
            data[j + k] = _mm256_or_si256(u, _mm256_permute2x128_si256( x , x , 1));
            data[j + n + k] = _mm256_or_si256(_mm256_permute2x128_si256( v , v , 1), y);
          }
        }
    }
  }
  
  
  
  #define NB_LOOP 200000
  
  int main() {
    __m256i data[256];
    for (int i = 0; i < 256; i++)
      data[i] =  _mm256_set_epi64x(rand(),rand(),rand(),rand());
  
    for (int i = 0; i < 100000; i++)
      orthogonalize(data);
  
    uint64_t timer = _rdtsc();
    for (int i = 0; i < NB_LOOP; i++)
      orthogonalize(data);
    timer = _rdtsc() - timer;
  
    printf("%.2f cycles/byte\n", (double)timer / NB_LOOP / (32*256));
  
  
    FILE* FP = fopen("/dev/null","w");
    fwrite(data,32,256,FP);
    fclose(FP);
  }
  