目次: ベンチマーク
musl C library(サイトへのリンク)のmemset関数の実装はかなり気合が入っており、特に先頭&終端データの処理が面白いです。
こんなコードです。
if (!n) return dest;
s[0] = c;
s[n-1] = c;
if (n <= 2) return dest;
s[1] = c;
s[2] = c;
s[n-2] = c;
s[n-3] = c;
if (n <= 6) return dest;
s[3] = c;
s[n-4] = c;
if (n <= 8) return dest;
私はぱっと見では何をしてるのかさっぱりわかりませんでした。図を書いてみてやっと意味が分かりました。
領域のサイズnが1〜8の場合、このコードだけで処理が終わります。説明の都合上、ifを区切りとして、3つのかたまり(赤、緑、青)に分けました。n = 1, 2の場合は赤だけ、n = 3, 4, 5, 6の場合は赤+緑、n = 7, 8の場合は赤+緑+青が実行されます。
ゴチャゴチャ説明するより、1ステップずつ、実行した結果を図示した方がわかりやすいかと思います。

s[n - 1] = cまで、
n = 1, 2はmemset完了

s[n - 2] = c, s[n - 3] = cまで、
n = 3, 4, 5, 6はmemset完了

s[n - 4] = cまで、
n = 7, 8はmemset完了、それ以上のサイズは処理を継続
図を見るとわかるように、同じ領域に2回以上書く場合がありますが、memsetは同じ領域に2度書いても問題ありません(書き込む値は同じなので、何度書いても結果は同じ)。
この「何度書いても良い」性質を利用して、分岐を限界まで減らす戦略のようです。
ストアより分岐を減らす方がメリットがある、とみているわけですね。イマドキのCPUに合った最適化なのでしょうね。
メモ: 技術系の話はFacebookから転記しておくことにした。大幅に追記。
この記事にコメントする
| < | 2019 | > | ||||
| << | < | 12 | > | >> | ||
| 日 | 月 | 火 | 水 | 木 | 金 | 土 |
| 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年12月26日
23年4月10日
25年12月22日
21年12月28日
08年3月25日
25年12月10日
25年12月16日
16年3月2日
25年12月19日
25年12月8日
25年12月18日
25年12月11日
22年4月13日
16年1月25日
16年1月8日
13年8月11日
23年9月11日
08年9月10日
08年9月11日
22年8月16日
wiki
Linux JM
Java API
2002年
2003年
2004年
2005年
2006年
2007年
2008年
2009年
2010年
2011年
2012年
2013年
2014年
2015年
2016年
2017年
2018年
2019年
2020年
2021年
2022年
2023年
2024年
2025年
2026年
過去日記について
アクセス統計
サーバ一覧
サイトの情報合計:
本日: