目次: ベンチマーク
NEON intrinsicを使って自分でmemsetを実装してみました。ざっくりした設計方針としては、
相手は汎用実装ですし、Cortex-A72に特化した実装なら楽勝だろう、などと考えて始めましたが、甘かった。glibcのフルアセンブラ版はかなり手ごわいです。
グラフの赤い線が、自作したmemsetの性能です。
最適化レベルO3のsimple memsetにはほぼ全域で勝てますが、サイズが小さいときのmuslは強い(サイズが小さい場合から判定しているから?)です。glibcのフルアセンブラもかなり強いです。測定によって勝ったり負けたりな程度です。
設計が甘すぎたことがわかったので、下記のように見直しました。
序盤でmusl memsetに負けていたのは、バイト数の条件判定の順序が良くなかった(大きいサイズから判定していた)ためなので、1番目で対策しています。2番目と3番目の方針は良いとも悪いとも一概に言えませんが、RK3399だとこれが一番性能が出ました。
設計意図通りにmuslの序盤(特に高速な1〜8バイト付近)と、glibcフルアセンブラの序盤(1〜32バイト)には勝てたものの、glibcフルアセンブラ版は中盤以降が強く、33バイト以降は全く勝てません。
私の作ったmemsetは32バイトまでは専用処理で、33バイトからループで処理するようになるので、33バイトから性能がかなり落ちます。
おそらくglibcフルアセンブラ版も同様に16バイトから性能が落ちるので、ループ処理していると思うんですが、それ以降の巻き返しが凄くて、33バイト以降はまったく勝てないですね……。どうやってんだろうね、これ?
コンパイラが変なandとかsubを出力しているのを見つけたので、アセンブラでも実装してみましたが、性能はほぼ変わりませんでした。設計の根底が違うんでしょうね。
RK3328(Cortex-A53)で測ってみると、muslには勝てますが、glibcフルアセンブラ版には勝ち目無しで、ほぼ全域に渡ってボコボコにされます。
基本設計が「余計なwriteをしてでも、とにかく速く終われ」なので、writeを正直に実行してしまうようなヘボいプロセッサになればなるほど勝ち目が薄いです。
 この記事にコメントする
 この記事にコメントする
目次: ベンチマーク
Cortex-A72でのmemsetはO2に-ftree-vectorizeと -fpeel-loopsを足すと、O3の性能とほぼイコールになることがわかりました。

gcc -O2 -ftree-vectorize -fpeel-loops -fno-builtinの測定結果(Cortex-A72)
元の処理が非常に単純なループ処理のためか、ループ系の最適化がメチャクチャ効くっぽいです。
GCCのGIMPLEを出力させ(-fdump-tree-all)眺めてみると、
こんな感じに見えます。正直言って、ループアンローリングなんて大したことないと思っていましたが、これほど効くとは思いませんでした。
メモ: 技術系の話はFacebookから転記しておくことにした。大幅に追記。
 この記事にコメントする
 この記事にコメントする
目次: ベンチマーク
(参考)コード一式はGitHubに置きました(GitHubへのリンク)
AArch64その2です。Cortex-A53でmemsetをやってみました。環境はRK3328 Cotex-A53 1.4GHzです。メモリはおそらくLPDDR3-1600です。
Cortex-A72と似ている点としては、
違う点としては、
こんなところでしょうか。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 | > | ||||
| << | < | 01 | > | >> | ||
| 日 | 月 | 火 | 水 | 木 | 金 | 土 | 
| - | - | - | 1 | 2 | 3 | 4 | 
| 5 | 6 | 7 | 8 | 9 | 10 | 11 | 
| 12 | 13 | 14 | 15 | 16 | 17 | 18 | 
| 19 | 20 | 21 | 22 | 23 | 24 | 25 | 
| 26 | 27 | 28 | 29 | 30 | 31 | - | 
 25年10月27日
 25年10月27日
 23年4月10日
 23年4月10日
 25年10月15日
 25年10月15日
 25年10月18日
 25年10月18日
 22年5月5日
 22年5月5日
 25年10月19日
 25年10月19日
 23年4月11日
 23年4月11日
 06年4月22日
 06年4月22日
 25年10月17日
 25年10月17日
 25年10月6日
 25年10月6日
 25年10月13日
 25年10月13日
 20年10月23日
 20年10月23日
 25年10月12日
 25年10月12日
 20年8月29日
 20年8月29日
 19年1月13日
 19年1月13日
 18年10月13日
 18年10月13日
 18年9月3日
 18年9月3日
 18年8月20日
 18年8月20日
 18年7月23日
 18年7月23日
 18年7月22日
 18年7月22日
 wiki
 wiki Linux JM
 Linux JM Java API
 Java API 2002年
 2002年 2003年
 2003年 2004年
 2004年 2005年
 2005年 2006年
 2006年 2007年
 2007年 2008年
 2008年 2009年
 2009年 2010年
 2010年 2011年
 2011年 2012年
 2012年 2013年
 2013年 2014年
 2014年 2015年
 2015年 2016年
 2016年 2017年
 2017年 2018年
 2018年 2019年
 2019年 2020年
 2020年 2021年
 2021年 2022年
 2022年 2023年
 2023年 2024年
 2024年 2025年
 2025年 過去日記について
 過去日記について アクセス統計
 アクセス統計 サーバ一覧
 サーバ一覧 サイトの情報
 サイトの情報合計: 
本日: