SlideShare a Scribd company logo
1 of 28
SIMDで整数除算
  @Shobomaru
更新履歴

• 2012/11/01 v1.0
  Slideshareのテストも兼ねて試験的に公開




            (´・ω・`)Shobomaru   2
2011年12月下旬くらいの出来事


( ^o^) SIMDで遊ぼう!

( ˘⊖˘) 。o( 待てよ?浮動小数点数の除算はrcpss命令だけど、整数の除算は? )

| In●el |┗(☋` )┓三

( ◠‿◠ )☛ そこに気づいたか・・・消えてもらう

▂▅▇█▓▒░(’ω’)░▒▓█▇▅▂うわああああああ




                      (´・ω・`)Shobomaru    3
詰んだ?


• 詰んだ。終了。解散。




• …ただし、除数が固定かつ16bit以下なら
  まだ希望がある




           (´・ω・`)Shobomaru   4
おさらい・浮動小数点数の除算

• 直接除算する方法
 – __m128 _mm_div_ps( __m128 a, __m128 b );
    • DIVPS xmm1, xmm2 (SSE1)
    • 遅い代わりに精度が高い
       – スループットは1/20、遅すぎ

• 逆数を求めて乗算にする方法
 – __m128 _mm_rcp_ps( __m128 a );
    • RCPPS xmm1, xmm2 (SSE1)
    • 速い代わりに精度が低い
       – その後乗算も必要




                      (´・ω・`)Shobomaru        5
おさらい・逆数による除算から乗算への変換

• 例:“8.0÷5.0=1.6”
  – = 8.0×(1.0÷5.0)
  – = 8.0×0.2 // ←この“0.2”を求めるのが逆数命令
  – = 1.6




                    (´・ω・`)Shobomaru   6
整数の除算

• 除算命令
 – ない…
• 逆数命令
 – ない…
• 右シフト命令
 – 2の冪乗でしか使えない


• ⇒ なんとか自分で逆数を求めるしかない
 – でも逆数は1以下なので、整数では表現できない…


           (´・ω・`)Shobomaru   7
整数を固定小数として扱う

• 最上位ビット(MSB)が0.5、MSBの隣が0.25、
  その隣が0.125…
• 例:“0.2”
 – = 0.125 + 0.0625 + 0.00078125 + 0.000390625 + …
 – 2進数表現では(とりえず16bitで)
   “0.0011001100110011”
 – 小数点以下を固定小数として取り出す
   “13037”
 – 固定小数なので、2^16である“65536”が1を表す
    • 13037÷65536=0.199996948242188≒0.2



                     (´・ω・`)Shobomaru                8
固定小数の掛け算

• 例:“8÷5”
  – = 8×13037÷65536
    • この除算は16bit論理右シフトで代用可能
      “(8*13037) >> 16”
  – = 1.5999755859375
  – 整数でキャストして答えは“1”
         _,,-―=''' ̄           ___,,-―――='' ̄ __,-―='' ̄           /
              _,,-―=''' ̄                _,,-―='' ̄ ヽ               /     +
          ̄ ̄               _,,-―=''' ̄                   \        /    . . .     .
                    ,,-='' ̄       _ノ                 ,_ノ ヽ      /         .  。. ★     ☆
               ,,,-''             / iニ)ヽ,             /rj:ヽヽ ヽ/             。.       .
         -―'' ̄               ;〈 !:::::::c! |___,/' {.::::::;、! } |        -┼- 丿~~~| |~~~~~| __ ■
         .   |.                   (つ`''"     |      / `'ー''(つ. |.    -┼- /~~~~/      丿 | 丿 ▼ ▼
             | .            /////         |       /       /// |     |        丿    /     丿    ● ●
             ヽ       γ´~⌒ヽ.               |     /             /
         ――ヽ      /         ヽ            | /               /⌒ヽ、
                \/             |            |_/           /      ヽ



                              (´・ω・`)Shobomaru                                         9
精度の問題

• この方法で“10÷5”を計算すると…
 – 10×13037÷65536
 – = 1.99996948242188
 – 整数でキャストして“1”…???
        ,,-―=''' ̄            ___,,-―――='' ̄ __,-―='' ̄               /
              _,,-―=''' ̄                _,,-―='' ̄ ヽ                  /     +
         ̄ ̄                _,,-―=''' ̄                   \           /   . . .      .
                   ,,-='' ̄       _ノ               ,_ノ      ヽ       /         .   。. ★    ☆
              ,,,-''             / iニ)ヽ,            /rj:ヽヽ       ヽ/            。.       .
        -―'' ̄                ;〈 !:::::::c!          ' {.::::::;、! 〉      |      ̄ ̄| _|_       丿 |~~~~~|
        .   |                    (つ`''"      __ `'ー''(つ          |         |     | /|.        丿 | 丿
            |          /////               |   |         /// |       __|       丿      |    /    丿
           ヽ        γ´~⌒ヽ.               /      |              /
        ――ヽ      /           ヽ        /         |            /⌒ヽ、
               \/              |        | ̄ ̄ ̄ ̄|           /          ヽ


• なぜ?
 – 逆数の丸め誤差を考慮していないから
                              (´・ω・`)Shobomaru                                             10
Terje Mathisenのアルゴリズム(?) [1]

• 逆数の小数点の位置をできるだけ右にずらす
 – 代償として、乗算後の論理右シフトの量を調整する

    xを割られる数、dを割る数とするとき、
    b = (有効ビット数) – 1
    r=w+b
    f = 2r / d
    もしfが整数ならば、case Aへ
    もしfの小数部が0.5未満ならば、case Bへ
    もしfの小数部が0.5を超えるならば、case Cへ
    case A: result = x SHR b
    case B: result = ( ( x + 1 ) * f ) SHR r
               ただし、fは切り捨て
    case C: result = ( x * f ) SHR r
               ただし、fは切り上げ
                                    SHRは論理右シフトのこと

                    (´・ω・`)Shobomaru                11
C言語のプログラム(1)
                                             引数        意味

int short_rcp(                                 div        割る数
unsigned short div,                            rcp         逆数
unsigned short *rcp,
int *shift,                                   shift    論理右シフト量
unsigned short *bias )                        bias         補正
{
       int b = 0;                            戻り値     divが2の冪乗か否か
       for( int i = 0; i < 16; i++ ) {
               if( ( ( div >> ( 15 - i ) ) & 0x1 ) == 1 ) {
                       b = 15 - i;
                       break;
               }
       }

       unsigned int r = 16 + b;
       unsigned int r2 = 1 << r;
       double f = (double)r2 / div;
       double fm = fmod( f, 1.0 );


                          (´・ω・`)Shobomaru                   12
C言語のプログラム(2)
    if( fm == 0.0 )
    {
           *shift = b;
           *rcp = 1;
           *bias = 0;
           return 1;
    }
    else if( fm < 0.5 )
    {
           *shift = b;
           *rcp = (unsigned short)f;
           *bias = 1;
           return 0;
    }
    else
    {
           *shift = b;
           *rcp = (unsigned short)( f + 0.5 );
           *bias = 0;
           return 0;
    }
}                      (´・ω・`)Shobomaru          13
C言語のプログラム(3)
const unsigned   short dividend = 10;
const unsigned   short divisor = 5;
unsigned short   rcp;
int shift;
unsigned short   bias;

int ans;
int pow2 = short_rcp( divisor, &rcp, &shift, &bias );
if( pow2 ) ans = dividend >> shift;
else       ans = ( ( dividend + bias ) * rcp ) >> ( shift + 16 );

• ansは期待通り”2”
• 割られる数が32769以上のとき、不正な解を出す
   – C言語の整数拡張ルールの関係で、乗算が符号付きに
     なってしまう
   – 楽しいアセンブラプログラミングが待ち受ける

                            (´・ω・`)Shobomaru                    14
逆数求めるの面倒すぎじゃね?

• だから言っただろう、
  「ただし、除数が固定なら」と。
 – 面倒な計算も初回だけなら我慢できる


• 除数が固定なら、変数pow2も不変なので、
  条件分岐のコストは考えなくてよい
 – Branch Target Bufferのない糞CPUなんぞ知らん


• 整数拡張もSSEなら自分で操作できる
 – アセンブラいらない!

                (´・ω・`)Shobomaru       15
SSE2を使ったプログラム
__m128i   mdivident;
__m128i   mrcp = _mm_set1_epi16( rcp );
__m128i   mbias = _mm_set1_epi16( bias );
__m128i   mans;

mdivident = _mm_load_si128( [メモリアドレス] );
if( pow2 ) mans = _mm_srli_epi16( mdibident, shift );
else       mans = _mm_srli_epi16( _mm_mulhi_epu16(
       _mm_add_epi16( mdivident, mbias ), mrcp ), shift );

• _mm_mulhi_epi16 ()は乗算後の上位ビットを返す
   – 上位型への拡張は要らない
   – 【悲報】上位ビットを返す乗算は、符号つきorなしの
     16bit整数しかない
          • 8bitなら16bitにunpack、32bitは終了


                            (´・ω・`)Shobomaru                 16
割る数がUSHORT_MAXのときの問題


• biasが1、divisorが65535のとき、直後の加算で
  整数オーバーフローによって不正な解になる

• どうしようもないので、
  分岐してスカラで計算するか、
  型昇格するかで回避するしかない
 – できたらUSHORT_MAXが来ないようにする




             (´・ω・`)Shobomaru      17
実は賢いコンパイラ

• 実は、C言語で定数の除算式を書くと
  勝手に乗算+論理右シフトにしてくれる
      – 割る数が2の冪乗なら右シフトだけ

volatile unsigned int dividend = 8;
unsigned int ans = dividend / 5;

mov     ecx,   ***
mov     eax,   0CCCCCCDh
mul     eax,   ecx
shr     edx,   2

(Visual C++ 10.0 / Release)




                           (´・ω・`)Shobomaru   18
BSR命令を使った最適化(2)

• 実は、有効ビット数の計算はx86専用命令がある
• BSR命令
 – ただし、0(立っているビットがない)は未定義値
  • 除算なので、そもそも逆数に0が入ってくる時点でおかしい
     – assert()なりthrowなり自分で例外処理する
  • 0が未定義でないLZCNT命令もあるが、AMD専用(SSE4a)
 – イントリンシック命令
  • _BitScanReverse() (Visual C++) ※intrin.hをinclude
  • _bit_scan_reverse() (Intel C++ Compiler)
  • __builtin_clz() (GNU gcc)
     – ARMとかMIPSとかでも使える
     – xor 16を取る必要あり?(要確認)

                      (´・ω・`)Shobomaru                 19
BSR命令を使った最適化(2)
unsigned long bl;
_BitScanReverse( &bl, div );

//int b = 16;
//for( int i = 0; i < 16; i++ ) {
//     if( ( ( div >> ( 15 - i ) ) & 0x1 ) == 1 ) {
//             b = 15 - i;
//             break;
//     }
//}
int b = bl;

• といっても逆数を求める部分なので、
  効果はほとんどない



                          (´・ω・`)Shobomaru            20
_mm_set1_epi16()

• 実は複数の命令に変換されてしまう
  – mov + punpcklwd + pshufd


• SSSE3なら_mm_shuffle_pi8()、
  AVX1なら_mm_broadcastw_epi16()
  でpunpcklwdは不要になる
  – movは消せないけど、IvyBridgeからmovはリネームス
    テージで消滅するらしいから、多分気にしないでいい
    • AMD?なにそれおいしいの?




                    (´・ω・`)Shobomaru   21
ベンチマーク


• …良く考えたら整数除算する機会ってなくね?

• てなわけで飽きました(:P




           (´・ω・`)Shobomaru   22
テーブル参照


• 除数固定、入力値の範囲が大きくなければ、
  SSEの代わりに除算結果のテーブルを
  作ってしまうのもアリ
 – テーブル参照なので、SSEは使えない




           (´・ω・`)Shobomaru   23
問題点

• SSE/AVXの乗算は16/32bit型だけ
 – 8bit型はpack/unpackで16bitに変換する必要あり


• 符号つき整数は一工夫必要
 – 乗算を符号付き、シフトを算術シフトにすればいい?
   • 試すのマンドクセ(‘A`)




                (´・ω・`)Shobomaru      24
ARM NEONでは…

• NEONも整数の除算はない
• 乗算はある
 – VQDMULH命令
   • ただし、符号つき16/32bitのみ…
 – VMULL命令
   • 符号なし8/16/32bit、後で自分で上位ビットを取り出す
• なぜか整数の逆数命令もある
 – VRECPE/VRECPS命令
   • 符号なし32bit(と32bit小数)
 – 精度とかはよく知らない
   • Newton-Raphson法が必要?試すのマンドクセ(‘A`)

                 (´・ω・`)Shobomaru       25
まとめ


• SSEに整数の除算命令はない

• なんとか逆数を作ることで、
  乗算を使って除算の代用が可能

• それでも制約がいっぱい
 – 早く整数除算命令を作ってくれ



           (´・ω・`)Shobomaru   26
参考文献


1. Optimizing subroutines in assembly language
   http://www.agner.org/optimize/optimizing_assem
   bly.pdf

• というか、ほぼパクリです。すみません。




                   (´・ω・`)Shobomaru            27
ライセンス


• このスライドは全て、
  「クリエイティブ・コモンズ 表示 2.1」
  の下で提供しています
  (ただし引用した図・文字を除く)




           (´・ω・`)Shobomaru   28

More Related Content

What's hot

指数時間アルゴリズム入門
指数時間アルゴリズム入門指数時間アルゴリズム入門
指数時間アルゴリズム入門Yoichi Iwata
 
いまさら聞けないarmを使ったNEONの基礎と活用事例
いまさら聞けないarmを使ったNEONの基礎と活用事例いまさら聞けないarmを使ったNEONの基礎と活用事例
いまさら聞けないarmを使ったNEONの基礎と活用事例Fixstars Corporation
 
条件分岐とcmovとmaxps
条件分岐とcmovとmaxps条件分岐とcmovとmaxps
条件分岐とcmovとmaxpsMITSUNARI Shigeo
 
マルチコアを用いた画像処理
マルチコアを用いた画像処理マルチコアを用いた画像処理
マルチコアを用いた画像処理Norishige Fukushima
 
計算機アーキテクチャを考慮した高能率画像処理プログラミング
計算機アーキテクチャを考慮した高能率画像処理プログラミング計算機アーキテクチャを考慮した高能率画像処理プログラミング
計算機アーキテクチャを考慮した高能率画像処理プログラミングNorishige Fukushima
 
新しい並列for構文のご提案
新しい並列for構文のご提案新しい並列for構文のご提案
新しい並列for構文のご提案yohhoy
 
Intro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみたIntro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみたMITSUNARI Shigeo
 
高速な倍精度指数関数expの実装
高速な倍精度指数関数expの実装高速な倍精度指数関数expの実装
高速な倍精度指数関数expの実装MITSUNARI Shigeo
 
最小カットを使って「燃やす埋める問題」を解く
最小カットを使って「燃やす埋める問題」を解く最小カットを使って「燃やす埋める問題」を解く
最小カットを使って「燃やす埋める問題」を解くshindannin
 
Xbyakの紹介とその周辺
Xbyakの紹介とその周辺Xbyakの紹介とその周辺
Xbyakの紹介とその周辺MITSUNARI Shigeo
 
ZDD入門-お姉さんを救う方法
ZDD入門-お姉さんを救う方法ZDD入門-お姉さんを救う方法
ZDD入門-お姉さんを救う方法nishio
 
Re永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライドRe永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライドMasaki Hara
 
いまさら聞けない!CUDA高速化入門
いまさら聞けない!CUDA高速化入門いまさら聞けない!CUDA高速化入門
いまさら聞けない!CUDA高速化入門Fixstars Corporation
 
ウェーブレット木の世界
ウェーブレット木の世界ウェーブレット木の世界
ウェーブレット木の世界Preferred Networks
 

What's hot (20)

フラグを愛でる
フラグを愛でるフラグを愛でる
フラグを愛でる
 
指数時間アルゴリズム入門
指数時間アルゴリズム入門指数時間アルゴリズム入門
指数時間アルゴリズム入門
 
いまさら聞けないarmを使ったNEONの基礎と活用事例
いまさら聞けないarmを使ったNEONの基礎と活用事例いまさら聞けないarmを使ったNEONの基礎と活用事例
いまさら聞けないarmを使ったNEONの基礎と活用事例
 
条件分岐とcmovとmaxps
条件分岐とcmovとmaxps条件分岐とcmovとmaxps
条件分岐とcmovとmaxps
 
マルチコアを用いた画像処理
マルチコアを用いた画像処理マルチコアを用いた画像処理
マルチコアを用いた画像処理
 
計算機アーキテクチャを考慮した高能率画像処理プログラミング
計算機アーキテクチャを考慮した高能率画像処理プログラミング計算機アーキテクチャを考慮した高能率画像処理プログラミング
計算機アーキテクチャを考慮した高能率画像処理プログラミング
 
新しい並列for構文のご提案
新しい並列for構文のご提案新しい並列for構文のご提案
新しい並列for構文のご提案
 
Intro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみたIntro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみた
 
双対性
双対性双対性
双対性
 
高速な倍精度指数関数expの実装
高速な倍精度指数関数expの実装高速な倍精度指数関数expの実装
高速な倍精度指数関数expの実装
 
最小カットを使って「燃やす埋める問題」を解く
最小カットを使って「燃やす埋める問題」を解く最小カットを使って「燃やす埋める問題」を解く
最小カットを使って「燃やす埋める問題」を解く
 
Xbyakの紹介とその周辺
Xbyakの紹介とその周辺Xbyakの紹介とその周辺
Xbyakの紹介とその周辺
 
最大流 (max flow)
最大流 (max flow)最大流 (max flow)
最大流 (max flow)
 
ZDD入門-お姉さんを救う方法
ZDD入門-お姉さんを救う方法ZDD入門-お姉さんを救う方法
ZDD入門-お姉さんを救う方法
 
Re永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライドRe永続データ構造が分からない人のためのスライド
Re永続データ構造が分からない人のためのスライド
 
いまさら聞けない!CUDA高速化入門
いまさら聞けない!CUDA高速化入門いまさら聞けない!CUDA高速化入門
いまさら聞けない!CUDA高速化入門
 
ウェーブレット木の世界
ウェーブレット木の世界ウェーブレット木の世界
ウェーブレット木の世界
 
Za atsu-20170328
Za atsu-20170328Za atsu-20170328
Za atsu-20170328
 
llvm入門
llvm入門llvm入門
llvm入門
 
動的計画法を極める!
動的計画法を極める!動的計画法を極める!
動的計画法を極める!
 

Viewers also liked

An OpenCL Method of Parallel Sorting Algorithms for GPU Architecture
An OpenCL Method of Parallel Sorting Algorithms for GPU ArchitectureAn OpenCL Method of Parallel Sorting Algorithms for GPU Architecture
An OpenCL Method of Parallel Sorting Algorithms for GPU ArchitectureWaqas Tariq
 
高位合成友の会第四回(2016/11/22)スライド
高位合成友の会第四回(2016/11/22)スライド高位合成友の会第四回(2016/11/22)スライド
高位合成友の会第四回(2016/11/22)スライド一路 川染
 
エンジニアにMacを薦める理由
エンジニアにMacを薦める理由エンジニアにMacを薦める理由
エンジニアにMacを薦める理由Hiroyuki Kusu
 
Editor縮小のススメ
Editor縮小のススメEditor縮小のススメ
Editor縮小のススメNobukazu Hanada
 
GPUによる多倍長整数乗算の高速化手法の提案
GPUによる多倍長整数乗算の高速化手法の提案GPUによる多倍長整数乗算の高速化手法の提案
GPUによる多倍長整数乗算の高速化手法の提案Koji Kitano
 
私がお世話になった技術書たち
私がお世話になった技術書たち私がお世話になった技術書たち
私がお世話になった技術書たち法林浩之
 
UNIXことはじめ
UNIXことはじめUNIXことはじめ
UNIXことはじめTomoya Miwa
 
Unixコマンド入門
Unixコマンド入門Unixコマンド入門
Unixコマンド入門Satosi Sakai
 
Xeonphiハッカソンでexpを作ってみた
Xeonphiハッカソンでexpを作ってみたXeonphiハッカソンでexpを作ってみた
Xeonphiハッカソンでexpを作ってみたMITSUNARI Shigeo
 
Unix 基礎
Unix 基礎Unix 基礎
Unix 基礎Sho A
 
Unixカーネルの設計 7 プロセスの制御
Unixカーネルの設計 7 プロセスの制御Unixカーネルの設計 7 プロセスの制御
Unixカーネルの設計 7 プロセスの制御Norito Agetsuma
 
templateとautoの型推論
templateとautoの型推論templateとautoの型推論
templateとautoの型推論MITSUNARI Shigeo
 
Unixファイルシステムの歴史
Unixファイルシステムの歴史Unixファイルシステムの歴史
Unixファイルシステムの歴史magoroku Yamamoto
 
詳解UNIXプログラミング 第4章 ファイルとディレクトリ
詳解UNIXプログラミング 第4章 ファイルとディレクトリ詳解UNIXプログラミング 第4章 ファイルとディレクトリ
詳解UNIXプログラミング 第4章 ファイルとディレクトリTakaya Kotohata
 
百万件くらいのデータの扱い方
百万件くらいのデータの扱い方百万件くらいのデータの扱い方
百万件くらいのデータの扱い方Masafumi Yokoyama
 
【幕張読書会】Unixカーネルの設計 3(バッファキャッシュ)
【幕張読書会】Unixカーネルの設計 3(バッファキャッシュ)【幕張読書会】Unixカーネルの設計 3(バッファキャッシュ)
【幕張読書会】Unixカーネルの設計 3(バッファキャッシュ)ktateish
 
Happy Optimization
Happy OptimizationHappy Optimization
Happy Optimizationguestee2c67
 

Viewers also liked (20)

The simd
The simdThe simd
The simd
 
An OpenCL Method of Parallel Sorting Algorithms for GPU Architecture
An OpenCL Method of Parallel Sorting Algorithms for GPU ArchitectureAn OpenCL Method of Parallel Sorting Algorithms for GPU Architecture
An OpenCL Method of Parallel Sorting Algorithms for GPU Architecture
 
高位合成友の会第四回(2016/11/22)スライド
高位合成友の会第四回(2016/11/22)スライド高位合成友の会第四回(2016/11/22)スライド
高位合成友の会第四回(2016/11/22)スライド
 
エンジニアにMacを薦める理由
エンジニアにMacを薦める理由エンジニアにMacを薦める理由
エンジニアにMacを薦める理由
 
Editor縮小のススメ
Editor縮小のススメEditor縮小のススメ
Editor縮小のススメ
 
GPUによる多倍長整数乗算の高速化手法の提案
GPUによる多倍長整数乗算の高速化手法の提案GPUによる多倍長整数乗算の高速化手法の提案
GPUによる多倍長整数乗算の高速化手法の提案
 
私がお世話になった技術書たち
私がお世話になった技術書たち私がお世話になった技術書たち
私がお世話になった技術書たち
 
UNIXことはじめ
UNIXことはじめUNIXことはじめ
UNIXことはじめ
 
Unixコマンド入門
Unixコマンド入門Unixコマンド入門
Unixコマンド入門
 
Xeonphiハッカソンでexpを作ってみた
Xeonphiハッカソンでexpを作ってみたXeonphiハッカソンでexpを作ってみた
Xeonphiハッカソンでexpを作ってみた
 
Boost.SIMD
Boost.SIMDBoost.SIMD
Boost.SIMD
 
PFI Seminar 2010/02/18
PFI Seminar 2010/02/18PFI Seminar 2010/02/18
PFI Seminar 2010/02/18
 
Unix 基礎
Unix 基礎Unix 基礎
Unix 基礎
 
Unixカーネルの設計 7 プロセスの制御
Unixカーネルの設計 7 プロセスの制御Unixカーネルの設計 7 プロセスの制御
Unixカーネルの設計 7 プロセスの制御
 
templateとautoの型推論
templateとautoの型推論templateとautoの型推論
templateとautoの型推論
 
Unixファイルシステムの歴史
Unixファイルシステムの歴史Unixファイルシステムの歴史
Unixファイルシステムの歴史
 
詳解UNIXプログラミング 第4章 ファイルとディレクトリ
詳解UNIXプログラミング 第4章 ファイルとディレクトリ詳解UNIXプログラミング 第4章 ファイルとディレクトリ
詳解UNIXプログラミング 第4章 ファイルとディレクトリ
 
百万件くらいのデータの扱い方
百万件くらいのデータの扱い方百万件くらいのデータの扱い方
百万件くらいのデータの扱い方
 
【幕張読書会】Unixカーネルの設計 3(バッファキャッシュ)
【幕張読書会】Unixカーネルの設計 3(バッファキャッシュ)【幕張読書会】Unixカーネルの設計 3(バッファキャッシュ)
【幕張読書会】Unixカーネルの設計 3(バッファキャッシュ)
 
Happy Optimization
Happy OptimizationHappy Optimization
Happy Optimization
 

Similar to SIMDで整数除算

Arduino 入門
Arduino 入門Arduino 入門
Arduino 入門mitunaga
 
競技プログラミングでの線型方程式系
競技プログラミングでの線型方程式系競技プログラミングでの線型方程式系
競技プログラミングでの線型方程式系tmaehara
 
V6でJIT・部分適用・継続
V6でJIT・部分適用・継続V6でJIT・部分適用・継続
V6でJIT・部分適用・継続7shi
 
C++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISるC++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISるHideyuki Tanaka
 
AtCoder Regular Contest 026 解説
AtCoder Regular Contest 026 解説AtCoder Regular Contest 026 解説
AtCoder Regular Contest 026 解説AtCoder Inc.
 
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由kikairoya
 
Goコンパイラのきもち
GoコンパイラのきもちGoコンパイラのきもち
Goコンパイラのきもちmjhd-devlion
 
30分で博士号がとれる画像処理講座
30分で博士号がとれる画像処理講座30分で博士号がとれる画像処理講座
30分で博士号がとれる画像処理講座Sakiyama Kei
 
Gc 擬(もどき)を js で書いてみた
Gc 擬(もどき)を js で書いてみた Gc 擬(もどき)を js で書いてみた
Gc 擬(もどき)を js で書いてみた to_ueda
 
虫食算を作るアルゴリズム 公表Ver
虫食算を作るアルゴリズム 公表Ver虫食算を作るアルゴリズム 公表Ver
虫食算を作るアルゴリズム 公表VerKensuke Otsuki
 
Designing video game hardware in verilog
Designing video game hardware in verilogDesigning video game hardware in verilog
Designing video game hardware in verilogAtsuki Takahashi
 

Similar to SIMDで整数除算 (12)

Arduino 入門
Arduino 入門Arduino 入門
Arduino 入門
 
HPC Phys-20201203
HPC Phys-20201203HPC Phys-20201203
HPC Phys-20201203
 
競技プログラミングでの線型方程式系
競技プログラミングでの線型方程式系競技プログラミングでの線型方程式系
競技プログラミングでの線型方程式系
 
V6でJIT・部分適用・継続
V6でJIT・部分適用・継続V6でJIT・部分適用・継続
V6でJIT・部分適用・継続
 
C++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISるC++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISる
 
AtCoder Regular Contest 026 解説
AtCoder Regular Contest 026 解説AtCoder Regular Contest 026 解説
AtCoder Regular Contest 026 解説
 
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由
 
Goコンパイラのきもち
GoコンパイラのきもちGoコンパイラのきもち
Goコンパイラのきもち
 
30分で博士号がとれる画像処理講座
30分で博士号がとれる画像処理講座30分で博士号がとれる画像処理講座
30分で博士号がとれる画像処理講座
 
Gc 擬(もどき)を js で書いてみた
Gc 擬(もどき)を js で書いてみた Gc 擬(もどき)を js で書いてみた
Gc 擬(もどき)を js で書いてみた
 
虫食算を作るアルゴリズム 公表Ver
虫食算を作るアルゴリズム 公表Ver虫食算を作るアルゴリズム 公表Ver
虫食算を作るアルゴリズム 公表Ver
 
Designing video game hardware in verilog
Designing video game hardware in verilogDesigning video game hardware in verilog
Designing video game hardware in verilog
 

Recently uploaded

AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfFumieNakayama
 
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?akihisamiyanaga1
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Yuma Ohgami
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)UEHARA, Tetsutaro
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...博三 太田
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdftaisei2219
 
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfFumieNakayama
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)Hiroki Ichikura
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNetToru Tamaki
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものですiPride Co., Ltd.
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A surveyToru Tamaki
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...Toru Tamaki
 
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案sugiuralab
 
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineerYuki Kikuchi
 

Recently uploaded (14)

AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
 
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdf
 
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものです
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
 
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
 
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
 

SIMDで整数除算

  • 2. 更新履歴 • 2012/11/01 v1.0 Slideshareのテストも兼ねて試験的に公開 (´・ω・`)Shobomaru 2
  • 3. 2011年12月下旬くらいの出来事 ( ^o^) SIMDで遊ぼう! ( ˘⊖˘) 。o( 待てよ?浮動小数点数の除算はrcpss命令だけど、整数の除算は? ) | In●el |┗(☋` )┓三 ( ◠‿◠ )☛ そこに気づいたか・・・消えてもらう ▂▅▇█▓▒░(’ω’)░▒▓█▇▅▂うわああああああ (´・ω・`)Shobomaru 3
  • 5. おさらい・浮動小数点数の除算 • 直接除算する方法 – __m128 _mm_div_ps( __m128 a, __m128 b ); • DIVPS xmm1, xmm2 (SSE1) • 遅い代わりに精度が高い – スループットは1/20、遅すぎ • 逆数を求めて乗算にする方法 – __m128 _mm_rcp_ps( __m128 a ); • RCPPS xmm1, xmm2 (SSE1) • 速い代わりに精度が低い – その後乗算も必要 (´・ω・`)Shobomaru 5
  • 6. おさらい・逆数による除算から乗算への変換 • 例:“8.0÷5.0=1.6” – = 8.0×(1.0÷5.0) – = 8.0×0.2 // ←この“0.2”を求めるのが逆数命令 – = 1.6 (´・ω・`)Shobomaru 6
  • 7. 整数の除算 • 除算命令 – ない… • 逆数命令 – ない… • 右シフト命令 – 2の冪乗でしか使えない • ⇒ なんとか自分で逆数を求めるしかない – でも逆数は1以下なので、整数では表現できない… (´・ω・`)Shobomaru 7
  • 8. 整数を固定小数として扱う • 最上位ビット(MSB)が0.5、MSBの隣が0.25、 その隣が0.125… • 例:“0.2” – = 0.125 + 0.0625 + 0.00078125 + 0.000390625 + … – 2進数表現では(とりえず16bitで) “0.0011001100110011” – 小数点以下を固定小数として取り出す “13037” – 固定小数なので、2^16である“65536”が1を表す • 13037÷65536=0.199996948242188≒0.2 (´・ω・`)Shobomaru 8
  • 9. 固定小数の掛け算 • 例:“8÷5” – = 8×13037÷65536 • この除算は16bit論理右シフトで代用可能 “(8*13037) >> 16” – = 1.5999755859375 – 整数でキャストして答えは“1” _,,-―=''' ̄ ___,,-―――='' ̄ __,-―='' ̄ / _,,-―=''' ̄ _,,-―='' ̄ ヽ / +  ̄ ̄ _,,-―=''' ̄ \ / . . . . ,,-='' ̄ _ノ ,_ノ ヽ / . 。. ★ ☆ ,,,-'' / iニ)ヽ, /rj:ヽヽ ヽ/ 。. . -―'' ̄ ;〈 !:::::::c! |___,/' {.::::::;、! } | -┼- 丿~~~| |~~~~~| __ ■ . |. (つ`''" | / `'ー''(つ. |. -┼- /~~~~/ 丿 | 丿 ▼ ▼ | . ///// | / /// | | 丿 / 丿 ● ● ヽ γ´~⌒ヽ. | / / ――ヽ / ヽ | / /⌒ヽ、 \/ | |_/ / ヽ (´・ω・`)Shobomaru 9
  • 10. 精度の問題 • この方法で“10÷5”を計算すると… – 10×13037÷65536 – = 1.99996948242188 – 整数でキャストして“1”…??? ,,-―=''' ̄ ___,,-―――='' ̄ __,-―='' ̄ / _,,-―=''' ̄ _,,-―='' ̄ ヽ / +  ̄ ̄ _,,-―=''' ̄ \ / . . . . ,,-='' ̄ _ノ ,_ノ ヽ / . 。. ★ ☆ ,,,-'' / iニ)ヽ, /rj:ヽヽ ヽ/ 。. . -―'' ̄ ;〈 !:::::::c! ' {.::::::;、! 〉 |  ̄ ̄| _|_ 丿 |~~~~~| . | (つ`''" __ `'ー''(つ | | | /|. 丿 | 丿 | ///// | | /// | __| 丿 | / 丿 ヽ γ´~⌒ヽ. / | / ――ヽ / ヽ / | /⌒ヽ、 \/ | | ̄ ̄ ̄ ̄| / ヽ • なぜ? – 逆数の丸め誤差を考慮していないから (´・ω・`)Shobomaru 10
  • 11. Terje Mathisenのアルゴリズム(?) [1] • 逆数の小数点の位置をできるだけ右にずらす – 代償として、乗算後の論理右シフトの量を調整する xを割られる数、dを割る数とするとき、 b = (有効ビット数) – 1 r=w+b f = 2r / d もしfが整数ならば、case Aへ もしfの小数部が0.5未満ならば、case Bへ もしfの小数部が0.5を超えるならば、case Cへ case A: result = x SHR b case B: result = ( ( x + 1 ) * f ) SHR r ただし、fは切り捨て case C: result = ( x * f ) SHR r ただし、fは切り上げ SHRは論理右シフトのこと (´・ω・`)Shobomaru 11
  • 12. C言語のプログラム(1) 引数 意味 int short_rcp( div 割る数 unsigned short div, rcp 逆数 unsigned short *rcp, int *shift, shift 論理右シフト量 unsigned short *bias ) bias 補正 { int b = 0; 戻り値 divが2の冪乗か否か for( int i = 0; i < 16; i++ ) { if( ( ( div >> ( 15 - i ) ) & 0x1 ) == 1 ) { b = 15 - i; break; } } unsigned int r = 16 + b; unsigned int r2 = 1 << r; double f = (double)r2 / div; double fm = fmod( f, 1.0 ); (´・ω・`)Shobomaru 12
  • 13. C言語のプログラム(2) if( fm == 0.0 ) { *shift = b; *rcp = 1; *bias = 0; return 1; } else if( fm < 0.5 ) { *shift = b; *rcp = (unsigned short)f; *bias = 1; return 0; } else { *shift = b; *rcp = (unsigned short)( f + 0.5 ); *bias = 0; return 0; } } (´・ω・`)Shobomaru 13
  • 14. C言語のプログラム(3) const unsigned short dividend = 10; const unsigned short divisor = 5; unsigned short rcp; int shift; unsigned short bias; int ans; int pow2 = short_rcp( divisor, &rcp, &shift, &bias ); if( pow2 ) ans = dividend >> shift; else ans = ( ( dividend + bias ) * rcp ) >> ( shift + 16 ); • ansは期待通り”2” • 割られる数が32769以上のとき、不正な解を出す – C言語の整数拡張ルールの関係で、乗算が符号付きに なってしまう – 楽しいアセンブラプログラミングが待ち受ける (´・ω・`)Shobomaru 14
  • 15. 逆数求めるの面倒すぎじゃね? • だから言っただろう、 「ただし、除数が固定なら」と。 – 面倒な計算も初回だけなら我慢できる • 除数が固定なら、変数pow2も不変なので、 条件分岐のコストは考えなくてよい – Branch Target Bufferのない糞CPUなんぞ知らん • 整数拡張もSSEなら自分で操作できる – アセンブラいらない! (´・ω・`)Shobomaru 15
  • 16. SSE2を使ったプログラム __m128i mdivident; __m128i mrcp = _mm_set1_epi16( rcp ); __m128i mbias = _mm_set1_epi16( bias ); __m128i mans; mdivident = _mm_load_si128( [メモリアドレス] ); if( pow2 ) mans = _mm_srli_epi16( mdibident, shift ); else mans = _mm_srli_epi16( _mm_mulhi_epu16( _mm_add_epi16( mdivident, mbias ), mrcp ), shift ); • _mm_mulhi_epi16 ()は乗算後の上位ビットを返す – 上位型への拡張は要らない – 【悲報】上位ビットを返す乗算は、符号つきorなしの 16bit整数しかない • 8bitなら16bitにunpack、32bitは終了 (´・ω・`)Shobomaru 16
  • 17. 割る数がUSHORT_MAXのときの問題 • biasが1、divisorが65535のとき、直後の加算で 整数オーバーフローによって不正な解になる • どうしようもないので、 分岐してスカラで計算するか、 型昇格するかで回避するしかない – できたらUSHORT_MAXが来ないようにする (´・ω・`)Shobomaru 17
  • 18. 実は賢いコンパイラ • 実は、C言語で定数の除算式を書くと 勝手に乗算+論理右シフトにしてくれる – 割る数が2の冪乗なら右シフトだけ volatile unsigned int dividend = 8; unsigned int ans = dividend / 5; mov ecx, *** mov eax, 0CCCCCCDh mul eax, ecx shr edx, 2 (Visual C++ 10.0 / Release) (´・ω・`)Shobomaru 18
  • 19. BSR命令を使った最適化(2) • 実は、有効ビット数の計算はx86専用命令がある • BSR命令 – ただし、0(立っているビットがない)は未定義値 • 除算なので、そもそも逆数に0が入ってくる時点でおかしい – assert()なりthrowなり自分で例外処理する • 0が未定義でないLZCNT命令もあるが、AMD専用(SSE4a) – イントリンシック命令 • _BitScanReverse() (Visual C++) ※intrin.hをinclude • _bit_scan_reverse() (Intel C++ Compiler) • __builtin_clz() (GNU gcc) – ARMとかMIPSとかでも使える – xor 16を取る必要あり?(要確認) (´・ω・`)Shobomaru 19
  • 20. BSR命令を使った最適化(2) unsigned long bl; _BitScanReverse( &bl, div ); //int b = 16; //for( int i = 0; i < 16; i++ ) { // if( ( ( div >> ( 15 - i ) ) & 0x1 ) == 1 ) { // b = 15 - i; // break; // } //} int b = bl; • といっても逆数を求める部分なので、 効果はほとんどない (´・ω・`)Shobomaru 20
  • 21. _mm_set1_epi16() • 実は複数の命令に変換されてしまう – mov + punpcklwd + pshufd • SSSE3なら_mm_shuffle_pi8()、 AVX1なら_mm_broadcastw_epi16() でpunpcklwdは不要になる – movは消せないけど、IvyBridgeからmovはリネームス テージで消滅するらしいから、多分気にしないでいい • AMD?なにそれおいしいの? (´・ω・`)Shobomaru 21
  • 23. テーブル参照 • 除数固定、入力値の範囲が大きくなければ、 SSEの代わりに除算結果のテーブルを 作ってしまうのもアリ – テーブル参照なので、SSEは使えない (´・ω・`)Shobomaru 23
  • 24. 問題点 • SSE/AVXの乗算は16/32bit型だけ – 8bit型はpack/unpackで16bitに変換する必要あり • 符号つき整数は一工夫必要 – 乗算を符号付き、シフトを算術シフトにすればいい? • 試すのマンドクセ(‘A`) (´・ω・`)Shobomaru 24
  • 25. ARM NEONでは… • NEONも整数の除算はない • 乗算はある – VQDMULH命令 • ただし、符号つき16/32bitのみ… – VMULL命令 • 符号なし8/16/32bit、後で自分で上位ビットを取り出す • なぜか整数の逆数命令もある – VRECPE/VRECPS命令 • 符号なし32bit(と32bit小数) – 精度とかはよく知らない • Newton-Raphson法が必要?試すのマンドクセ(‘A`) (´・ω・`)Shobomaru 25
  • 26. まとめ • SSEに整数の除算命令はない • なんとか逆数を作ることで、 乗算を使って除算の代用が可能 • それでも制約がいっぱい – 早く整数除算命令を作ってくれ (´・ω・`)Shobomaru 26
  • 27. 参考文献 1. Optimizing subroutines in assembly language http://www.agner.org/optimize/optimizing_assem bly.pdf • というか、ほぼパクリです。すみません。 (´・ω・`)Shobomaru 27
  • 28. ライセンス • このスライドは全て、 「クリエイティブ・コモンズ 表示 2.1」 の下で提供しています (ただし引用した図・文字を除く) (´・ω・`)Shobomaru 28