Cell SPUのスカラ演算、整数演算、分岐

「Cell SPUのスカラ演算、整数演算、分岐」の編集履歴(バックアップ)一覧はこちら

Cell SPUのスカラ演算、整数演算、分岐」(2008/11/17 (月) 00:46:14) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

比較対象がないと速いか遅いかを論じるのは意味なし。 なので結論は出さず。 最初に参考リンク - [[SPEにおけるスカラ演算 (フィックスターズ)>http://cell.fixstars.com/ps3linux/index.php/4.5%E3%80%80SPE%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%82%B9%E3%82%AB%E3%83%A9%E6%BC%94%E7%AE%97]] - [[何で私のスカラーコードはこんなに遅いの? (IBM developer Works)>http://www.ibm.com/developerworks/jp/power/library/pa-tacklecell3/index.html]] - [[相乗演算処理装置の紹介 (IBM developer Works)>www.ibm.com/developerworks/jp/linux/library/pa-linuxps3-3/index.html]] 目次 #contents() ---- *SPUの整数演算は遅いか? 整数演算の性能は次の通り - 128bit x1 論理演算 - 32bit x4 四則演算、論理演算 - 16bit x4 積和演算 - 16bit x8 四則演算、論理演算 - 8bit x16 特殊演算 が毎サイクル実行可能、レイテンシは2、または4サイクル。 ちなみに浮動少数演算の性能は次の通り - float x4 積和演算 が毎サイクル実行可能、レイテンシが6サイクル - double x2 積和 が7サイクルで実行可能、レイテンシが13サイクル *SPUの分岐は遅いか? パイプラインが26段と深いため、分岐予測が外れた場合のペナルティは17~18サイクルと大きい。 ハードウエアで動的分岐予測機構を持たないが、ソフトウェア的に分岐ヒント命令と条件選択命令を持つ。 分岐ヒントの予測が正しければ分岐のペナルティは0。 また2値のいずれかの選択だけの分岐であるなら、投機的に2値をどちらも計算した上で条件選択命令を使うことで 分岐自体をなくすことが可能。 *SPUのスカラ演算は遅いか? SIMD演算器しかないのでスカラ演算でもそこで行う。 なので計算の速さはスカラでもベクタでも同じ。 ただしスカラの場合は、上記フィックスターズの記事にあるとおりLSからのロード、LSへのストアで 無駄が発生することが多い。 とは言っても128bitレジスタが128本あるので可能な限りオンレジスタで演算させるのがSPU流なので、 LSへのアクセスも必要最小限にとどまると思われる。 **ロード #highlight(linenumber){ # アライメントがとれていないbyteをロードする # $ra : アドレス # $rb : 結果をいれる # $raの下位4bitは無視されるため自動的に16バイトアラインでロードされる lqd $rb, 0($ra) # $raの下位4bitを使って$rtをバイト単位でローテートすることでMSBに移動させる rotqby $rb, $rb, $ra # プリファードスロットへさらにローテート rotqbyi $rb, $rb, -3 } byte、halfwordの場合だけ12.のローテートが必要。 アライメントがとれていれば6.の1命令だけでいい。 **ストア #highlight(linenumber){ # byteをストアする # $ra : アドレス # $rb : バイトデータ # $rc, rd, re : テンポラリ # まずストア位置のデータをロードする lqd $rc, 0($ra) # バイト挿入マスクの生成 cbd $rd, 0($ra) # シャッフル # rbのプリファードスロットとrcのプリファードスロット以外とを合成する shufb $re, $rb, $rc, $rd # ストアする stqd $re, 0($ra) } ストアはアライメントがとれてる/とれていないにかかわらず基本的に上記の手順が必要。 クアッドワードならもちろん1命令で可能。 *32bitの乗算がないってほんと? まじで32bitの整数乗算をするインストラクションはない。 16bitの乗算命令(出力は32bit)を組み合わせて実現する。 一般的に5つのインストラクションが必要。 例 #highlight(linenumber){{ int32_t mul_s32x2_to_s32(int32_t a, int32_t b) { return a * b; } }} 次のようにコンパイルされる #highlight(linenumber){ # $3 : a # $4 : b # aの上位ハーフワードとbの下位ハーフワードを乗算 mpyh $6,$3,$4 # bの上位ハーフワードとaの下位ハーフワードを乗算 mpyh $5,$4,$3 # aの下位ハーフワードとbの下位ハーフワードを符号無しで乗算 mpyu $3,$3,$4 # 以上をすべて足し合わせる # 32bitに収まることが前提なので上位ハーフワード同士の乗算は行わない a $2,$6,$5 a $3,$2,$3 # リターン bi $0 } *LSはL1並に速いか? load/store のレイテンシは6サイクル ----
比較対象がないと速いか遅いかを論じるのは意味なし。 なので結論は出さず。 最初に参考リンク - [[SPEにおけるスカラ演算 (フィックスターズ)>http://cell.fixstars.com/ps3linux/index.php/4.5%E3%80%80SPE%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%82%B9%E3%82%AB%E3%83%A9%E6%BC%94%E7%AE%97]] - [[何で私のスカラーコードはこんなに遅いの? (IBM developer Works)>http://www.ibm.com/developerworks/jp/power/library/pa-tacklecell3/index.html]] - [[相乗演算処理装置の紹介 (IBM developer Works)>http://www.ibm.com/developerworks/jp/linux/library/pa-linuxps3-3/]] 目次 #contents() ---- *SPUの整数演算は遅いか? 整数演算の性能は次の通り - 128bit x1 論理演算 - 32bit x4 四則演算、論理演算 - 16bit x4 積和演算 - 16bit x8 四則演算、論理演算 - 8bit x16 特殊演算 が毎サイクル実行可能、レイテンシは2、または4サイクル。 ちなみに浮動少数演算の性能は次の通り - float x4 積和演算 が毎サイクル実行可能、レイテンシが6サイクル - double x2 積和 が7サイクルで実行可能、レイテンシが13サイクル *SPUの分岐は遅いか? パイプラインが26段と深いため、分岐予測が外れた場合のペナルティは17~18サイクルと大きい。 ハードウエアで動的分岐予測機構を持たないが、ソフトウェア的に分岐ヒント命令と条件選択命令を持つ。 分岐ヒントの予測が正しければ分岐のペナルティは0。 また2値のいずれかの選択だけの分岐であるなら、投機的に2値をどちらも計算した上で条件選択命令を使うことで 分岐自体をなくすことが可能。 *SPUのスカラ演算は遅いか? SIMD演算器しかないのでスカラ演算でもそこで行う。 なので計算の速さはスカラでもベクタでも同じ。 ただしスカラの場合は、上記フィックスターズの記事にあるとおりLSからのロード、LSへのストアで 無駄が発生することが多い。 とは言っても128bitレジスタが128本あるので可能な限りオンレジスタで演算させるのがSPU流なので、 LSへのアクセスも必要最小限にとどまると思われる。 **ロード #highlight(linenumber){ # アライメントがとれていないbyteをロードする # $ra : アドレス # $rb : 結果をいれる # $raの下位4bitは無視されるため自動的に16バイトアラインでロードされる lqd $rb, 0($ra) # $raの下位4bitを使って$rtをバイト単位でローテートすることでMSBに移動させる rotqby $rb, $rb, $ra # プリファードスロットへさらにローテート rotqbyi $rb, $rb, -3 } byte、halfwordの場合だけ12.のローテートが必要。 アライメントがとれていれば6.の1命令だけでいい。 **ストア #highlight(linenumber){ # byteをストアする # $ra : アドレス # $rb : バイトデータ # $rc, rd, re : テンポラリ # まずストア位置のデータをロードする lqd $rc, 0($ra) # バイト挿入マスクの生成 cbd $rd, 0($ra) # シャッフル # rbのプリファードスロットとrcのプリファードスロット以外とを合成する shufb $re, $rb, $rc, $rd # ストアする stqd $re, 0($ra) } ストアはアライメントがとれてる/とれていないにかかわらず基本的に上記の手順が必要。 クアッドワードならもちろん1命令で可能。 *32bitの乗算がないってほんと? まじで32bitの整数乗算をするインストラクションはない。 16bitの乗算命令(出力は32bit)を組み合わせて実現する。 一般的に5つのインストラクションが必要。 例 #highlight(linenumber){{ int32_t mul_s32x2_to_s32(int32_t a, int32_t b) { return a * b; } }} 次のようにコンパイルされる #highlight(linenumber){ # $3 : a # $4 : b # aの上位ハーフワードとbの下位ハーフワードを乗算 mpyh $6,$3,$4 # bの上位ハーフワードとaの下位ハーフワードを乗算 mpyh $5,$4,$3 # aの下位ハーフワードとbの下位ハーフワードを符号無しで乗算 mpyu $3,$3,$4 # 以上をすべて足し合わせる # 32bitに収まることが前提なので上位ハーフワード同士の乗算は行わない a $2,$6,$5 a $3,$2,$3 # リターン bi $0 } *LSはL1並に速いか? load/store のレイテンシは6サイクル ----

表示オプション

横に並べて表示:
変化行の前後のみ表示:
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。