LoginSignup
3
1

More than 5 years have passed since last update.

SIMDのset関連の速度

Posted at

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

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1