setとかloadとかの速度が気になる。
試そう。
#include <stdio.h>
#include <immintrin.h>
float data[8][8] = {
{7.f, 6.f, 5.f, 4.f, 3.f, 2.f, 1.f, 0.f},
{7.f, 6.f, 5.f, 4.f, 3.f, 2.f, 1.f, 1.f},
{7.f, 6.f, 5.f, 4.f, 3.f, 2.f, 1.f, 2.f},
{7.f, 6.f, 5.f, 4.f, 3.f, 2.f, 1.f, 3.f},
{7.f, 6.f, 5.f, 4.f, 3.f, 2.f, 1.f, 4.f},
{7.f, 6.f, 5.f, 4.f, 3.f, 2.f, 1.f, 5.f},
{7.f, 6.f, 5.f, 4.f, 3.f, 2.f, 1.f, 6.f},
{7.f, 6.f, 5.f, 4.f, 3.f, 2.f, 1.f, 7.f}
};
void set()
{
const __m256 ymm_index_base0 = _mm256_set_ps(7.f, 6.f, 5.f, 4.f, 3.f, 2.f, 1.f, 0.f);
const __m256 ymm_index_base1 = _mm256_set_ps(7.f, 6.f, 5.f, 4.f, 3.f, 2.f, 1.f, 1.f);
const __m256 ymm_index_base2 = _mm256_set_ps(7.f, 6.f, 5.f, 4.f, 3.f, 2.f, 1.f, 2.f);
const __m256 ymm_index_base3 = _mm256_set_ps(7.f, 6.f, 5.f, 4.f, 3.f, 2.f, 1.f, 3.f);
const __m256 ymm_index_base4 = _mm256_set_ps(7.f, 6.f, 5.f, 4.f, 3.f, 2.f, 1.f, 4.f);
const __m256 ymm_index_base5 = _mm256_set_ps(7.f, 6.f, 5.f, 4.f, 3.f, 2.f, 1.f, 5.f);
const __m256 ymm_index_base6 = _mm256_set_ps(7.f, 6.f, 5.f, 4.f, 3.f, 2.f, 1.f, 6.f);
const __m256 ymm_index_base7 = _mm256_set_ps(7.f, 6.f, 5.f, 4.f, 3.f, 2.f, 1.f, 7.f);
__m256 ymm_index0 = _mm256_add_ps(ymm_index_base0 , ymm_index_base7);
__m256 ymm_index1 = _mm256_add_ps(ymm_index_base1 , ymm_index_base6);
__m256 ymm_index2 = _mm256_add_ps(ymm_index_base2 , ymm_index_base5);
__m256 ymm_index3 = _mm256_add_ps(ymm_index_base3 , ymm_index_base4);
}
void setr()
{
const __m256 ymm_index_base0 = _mm256_setr_ps(7.f, 6.f, 5.f, 4.f, 3.f, 2.f, 1.f, 0.f);
const __m256 ymm_index_base1 = _mm256_setr_ps(7.f, 6.f, 5.f, 4.f, 3.f, 2.f, 1.f, 1.f);
const __m256 ymm_index_base2 = _mm256_setr_ps(7.f, 6.f, 5.f, 4.f, 3.f, 2.f, 1.f, 2.f);
const __m256 ymm_index_base3 = _mm256_setr_ps(7.f, 6.f, 5.f, 4.f, 3.f, 2.f, 1.f, 3.f);
const __m256 ymm_index_base4 = _mm256_setr_ps(7.f, 6.f, 5.f, 4.f, 3.f, 2.f, 1.f, 4.f);
const __m256 ymm_index_base5 = _mm256_setr_ps(7.f, 6.f, 5.f, 4.f, 3.f, 2.f, 1.f, 5.f);
const __m256 ymm_index_base6 = _mm256_setr_ps(7.f, 6.f, 5.f, 4.f, 3.f, 2.f, 1.f, 6.f);
const __m256 ymm_index_base7 = _mm256_setr_ps(7.f, 6.f, 5.f, 4.f, 3.f, 2.f, 1.f, 7.f);
__m256 ymm_index0 = _mm256_add_ps(ymm_index_base0 , ymm_index_base7);
__m256 ymm_index1 = _mm256_add_ps(ymm_index_base1 , ymm_index_base6);
__m256 ymm_index2 = _mm256_add_ps(ymm_index_base2 , ymm_index_base5);
__m256 ymm_index3 = _mm256_add_ps(ymm_index_base3 , ymm_index_base4);
}
void set1()
{
const __m256 ymm_index_base0 = _mm256_set1_ps(0.f);
const __m256 ymm_index_base1 = _mm256_set1_ps(1.f);
const __m256 ymm_index_base2 = _mm256_set1_ps(2.f);
const __m256 ymm_index_base3 = _mm256_set1_ps(3.f);
const __m256 ymm_index_base4 = _mm256_set1_ps(4.f);
const __m256 ymm_index_base5 = _mm256_set1_ps(5.f);
const __m256 ymm_index_base6 = _mm256_set1_ps(6.f);
const __m256 ymm_index_base7 = _mm256_set1_ps(7.f);
__m256 ymm_index0 = _mm256_add_ps(ymm_index_base0 , ymm_index_base7);
__m256 ymm_index1 = _mm256_add_ps(ymm_index_base1 , ymm_index_base6);
__m256 ymm_index2 = _mm256_add_ps(ymm_index_base2 , ymm_index_base5);
__m256 ymm_index3 = _mm256_add_ps(ymm_index_base3 , ymm_index_base4);
}
void load()
{
const __m256 ymm_index_base0 = _mm256_loadu_ps(data[0]);
const __m256 ymm_index_base1 = _mm256_loadu_ps(data[1]);
const __m256 ymm_index_base2 = _mm256_loadu_ps(data[2]);
const __m256 ymm_index_base3 = _mm256_loadu_ps(data[3]);
const __m256 ymm_index_base4 = _mm256_loadu_ps(data[4]);
const __m256 ymm_index_base5 = _mm256_loadu_ps(data[5]);
const __m256 ymm_index_base6 = _mm256_loadu_ps(data[6]);
const __m256 ymm_index_base7 = _mm256_loadu_ps(data[7]);
__m256 ymm_index0 = _mm256_add_ps(ymm_index_base0 , ymm_index_base7);
__m256 ymm_index1 = _mm256_add_ps(ymm_index_base1 , ymm_index_base6);
__m256 ymm_index2 = _mm256_add_ps(ymm_index_base2 , ymm_index_base5);
__m256 ymm_index3 = _mm256_add_ps(ymm_index_base3 , ymm_index_base4);
}
int main(){
const size_t n = 2345;
double t1 = gettimeofday_msec();
for (int i=0; i<n*n; i++) { set(); }
double t2 = gettimeofday_msec();
double t3 = gettimeofday_msec();
for (int i=0; i<n*n; i++) { set1(); }
double t4 = gettimeofday_msec();
double t5 = gettimeofday_msec();
for (int i=0; i<n*n; i++) { setr(); }
double t6 = gettimeofday_msec();
double t7 = gettimeofday_msec();
for (int i=0; i<n*n; i++) { load(); }
double t8 = gettimeofday_msec();
printf("set : %f msec\n", t2 - t1);
printf("set1: %f msec\n", t4 - t3);
printf("setr: %f msec\n", t6 - t5);
printf("load: %f msec\n", t8 - t7);
return 0;
}
結果
set : 226.044922 msec
set1: 56.011963 msec
setr: 319.062988 msec
load: 57.512207 msec
doubleに変えてみた。
set : 180.536865 msec
set1: 55.010986 msec
setr: 212.041992 msec
load: 57.010986 msec
int32に変えてみた。
set : 192.037842 msec
set1: 54.010986 msec
setr: 259.552002 msec
load: 57.511963 msec