link もっと前
   2020年 1月 14日 -
      2020年 1月 5日  
link もっと後

link 未来から過去へ表示(*)
link 過去から未来へ表示

link permalink

link 編集する

ぼくの考えた最強の memset

目次です。

NEON intrinsic を使って自分で memset を実装してみました。ざっくりした設計方針としては、

  • NEON store (128bit) x 2 で 32バイトずつ書く
  • 端数 25〜バイトは NEON store x 2
  • 端数 16〜バイトは NEON store + uint64 store

相手は汎用実装ですし、Cortex-A72 に特化した実装なら楽勝だろう、などと考えて始めましたが、甘かった。glibc のフルアセンブラ版はかなり手ごわいです。


自作 memset の測定結果(Cortex-A72)

グラフの赤い線が、自作した memset の性能です。

最適化レベル O3 の simple memset にはほぼ全域で勝てますが、サイズが小さいときの musl は強い(サイズが小さい場合から判定しているから?)です。glibc のフルアセンブラもかなり強いです。測定によって勝ったり負けたりな程度です。

全然最強じゃなかった……

設計が甘すぎたことがわかったので、下記のように見直しました。

  • 少ないバイト数の条件から判定
  • NEON store (128bit) x 2 で 32バイトずつ書く
  • 端数バイトは NEON store(分岐を減らした)

序盤で musl memset に負けていたのは、バイト数の条件判定の順序が良くなかった(大きいサイズから判定していた)ためなので、1番目で対策しています。2番目と 3番目の方針は良いとも悪いとも一概に言えませんが、RK3399 だとこれが一番性能が出ました。


自作 memset 改善後の測定結果(Cortex-A72)

設計意図通りに musl の序盤(特に高速な 1〜8バイト付近)と、glibc フルアセンブラの序盤(1〜32バイト)には勝てたものの、glibc フルアセンブラ版は中盤以降が強く、33バイト以降は全く勝てません。

私の作った memset は 32バイトまでは専用処理で、33バイトからループで処理するようになるので、33バイトから性能がかなり落ちます。

おそらく glibc フルアセンブラ版も同様に 16バイトから性能が落ちるので、ループ処理していると思うんですが、それ以降の巻き返しが凄くて、33バイト以降はまったく勝てないですね……。どうやってんだろうね、これ?

コンパイラが変な and とか sub を出力しているのを見つけたので、アセンブラでも実装してみましたが、性能はほぼ変わりませんでした。設計の根底が違うんでしょうね。

Cortex-A53 だと全く勝ち目無し

RK3328(Cortex-A53)で測ってみると、musl には勝てますが、glibc フルアセンブラ版には勝ち目無しで、ほぼ全域に渡ってボコボコにされます。


自作 memset 改善後の測定結果(Cortex-A53)

基本設計が「余計な write をしてでも、とにかく速く終われ」なので、write を正直に実行してしまうようなヘボいプロセッサになればなるほど勝ち目が薄いです。

[編集者: すずき]
[更新: 2020年 1月 26日 17:19]

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link permalink

link 編集する

memset に一番効く最適化

Cortex-A72 での memset は O2 に -ftree-vectorize と -fpeel-loops を足すと、O3 の性能とほぼイコールになることがわかりました。


gcc -O2 -ftree-vectorize -fpeel-loops -fno-builtin の測定結果(Cortex-A72)

元の処理が非常に単純なループ処理のためか、ループ系の最適化がメチャクチャ効くっぽいです。

何が効くのか?

GCC の GIMPLE を出力させ(-fdump-tree-all)眺めてみると、

オリジナル
1バイトごとにデータ処理するループが生成される。
ベクタライズ(161t.vect)
16バイトごとにデータ処理するループと、1バイトごとに残りデータを処理するループに分割される。
アンローリング(164t.cunroll, 169t.loopdone)
残りデータを処理するループが展開される。

こんな感じに見えます。正直言って、ループアンローリングなんて大したことないと思っていましたが、これほど効くとは思いませんでした。

メモ: 技術系の話は Facebook から転記しておくことにした。大幅に追記。

[編集者: すずき]
[更新: 2020年 1月 13日 00:42]

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link permalink

link 編集する

memset のベンチマーク(AArch64, Cortex-A53 編)

(参考)コード一式は GitHub に置きました(GitHub へのリンク

AArch64 その 2 です。Cortex-A53 で memset をやってみました。環境は RK3328 Cotex-A53 1.4GHz です。メモリはおそらく LPDDR3-1600 です。

Cortex-A72 と似ている点としては、

  • musl memset 関数が非常に優秀
  • ベクトル化は性能向上に効くが、他も有効な要素がありそう

違う点としては、

  • アセンブラ実装と musl memset 関数の差が開く
  • O3 の最適化がかなり効く(※)
  • glibc memset 関数の不安定さが減る

こんなところでしょうか。A72 の glibc memset 関数はグラフが上がったり下がったりグチャグチャしていましたが、A53 だと割と素直になっています。


gcc -O3 -fno-builtin の測定結果(Cortex-A53 編)


gcc -O2 -ftree-vectorize -fno-builtin の測定結果(Cortex-A53 編)


gcc -O2 -fno-builtin の測定結果(Cortex-A53 編)

(※)A72 では単純な memset 関数は musl memset 関数にほぼ勝てない(16〜22バイトのみ勝つ)が、A53 では割と良い勝負(16〜22、32〜38、48〜52バイトで勝つ)をしている。

[編集者: すずき]
[更新: 2020年 1月 12日 02:34]

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link もっと前
   2020年 1月 14日 -
      2020年 1月 5日  
link もっと後

管理用メニュー

link 記事を新規作成

合計:  counter total
本日:  counter today

link About www.katsuster.net
RDF ファイル RSS 1.0
QR コード QR コード

最終更新: 8/11 19:13

カレンダー

<2020>
<<<01>>>
---1234
567891011
12131415161718
19202122232425
262728293031-

最近のコメント 5件

  • link 20年07月10日
    すずき 「鳥のゲームは知りませんでした。色々やって...」
    (更新:08/11 18:59)
  • link 20年07月12日
    すずき 「小学生でサイトに投稿はスゴイです。そして...」
    (更新:08/11 18:59)
  • link 20年07月10日
    わしだ 「オープンブック9003時代に鳥(Pinn...」
    (更新:08/10 22:40)
  • link 20年07月12日
    わしだ 「The Tower懐かしいですね。\n話...」
    (更新:08/10 22:36)
  • link 20年08月06日
    すずき 「室内の銅配管は段々硬くなるので、床に落ち...」
    (更新:08/10 17:53)

最近の記事 20件

link もっとみる
  • link 20年07月11日
    すずき 「[STATIONflow 実績コンプリート] STATIONflo...」
    (更新:08/11 19:13)
  • link 20年07月01日
    すずき 「[STATIONflow ランク 100] STATIONflow...」
    (更新:08/11 19:13)
  • link 20年06月30日
    すずき 「[STATIONflow の駅の評価] STATIONflow の...」
    (更新:08/11 19:13)
  • link 20年06月28日
    すずき 「[STATIONflow まさかの実績解除方法] STATIONf...」
    (更新:08/11 19:13)
  • link 20年06月27日
    すずき 「[STATIONflow プレイ日記] STATIONflow の...」
    (更新:08/11 19:12)
  • link 20年06月26日
    すずき 「[STATIONflow 小技] STATIONflow の日記一...」
    (更新:08/11 19:12)
  • link 20年05月28日
    すずき 「[STATIONflow のバグ] STATIONflow の日記...」
    (更新:08/11 19:12)
  • link 20年05月27日
    すずき 「[STATIONflow ランク 20] STATIONflow ...」
    (更新:08/11 19:12)
  • link 20年05月19日
    すずき 「[STATIONflow 始めました、超えろ、新宿駅] STATI...」
    (更新:08/11 19:11)
  • link 20年08月03日
    すずき 「[SPDIF/HDMI ビットストリームパススルー] 以前(202...」
    (更新:08/10 20:22)
  • link 20年08月08日
    すずき 「[車検] 車検証と検査証票(フロントガラスに貼るステッカー)が届き...」
    (更新:08/08 14:35)
  • link 20年08月07日
    すずき 「[Wikipedia] Wikipedia に寄付しました。といっ...」
    (更新:08/08 14:24)
  • link 20年08月06日
    すずき 「[エアコンが落ちそうで怖い] Twitter で「これ便利」と紹介...」
    (更新:08/08 14:24)
  • link 20年08月02日
    すずき 「[RockPro64 の HDMI から音を出す] 今更ですが、メ...」
    (更新:08/08 14:14)
  • link 20年08月01日
    すずき 「[RockPro64 と音声ビットストリームパススルー出力] 去年...」
    (更新:08/02 22:39)
  • link 20年07月28日
    すずき 「[またバッテリー死す] コロナ騒ぎが始まって、遠出することもなくな...」
    (更新:07/29 21:06)
  • link 20年07月18日
    すずき 「[北極送り] GitHub が北極にコードを保存する取り組み(私の...」
    (更新:07/23 12:53)
  • link 19年09月06日
    すずき 「[RockPro64 とアナログオーディオ - その 3 - ] ...」
    (更新:07/23 03:31)
  • link 20年07月21日
    すずき 「[ARM SBC リスト] 最近はたくさんの ARM のシングルボ...」
    (更新:07/23 01:55)
  • link 20年06月02日
    すずき 「[GCC を調べる - まとめリンク] 日記が増えすぎて、一覧が欲...」
    (更新:07/23 00:28)

こんてんつ

open/close wiki
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 2018年
open/close 2019年
open/close 2020年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報