目次: ベンチマーク
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 | - | - | - | - |
26年2月11日
23年4月10日
23年5月15日
26年2月8日
26年2月9日
23年6月1日
24年2月2日
26年2月1日
21年5月7日
26年1月19日
26年1月29日
26年1月23日
26年1月21日
25年12月26日
25年12月22日
21年12月28日
08年3月25日
25年12月10日
25年12月16日
16年3月2日
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年
過去日記について
アクセス統計
サーバ一覧
サイトの情報合計:
本日: