プログラミングのお題スレ Part22 (860レス)
前次1-
抽出解除 レス栞

リロード規制です。10分ほどで解除するので、他のブラウザへ避難してください。
309
(1): デフォルトの名無しさん [sage] 2024/03/10(日) 20:08:55.20 ID:6qxPF4Wx(1) AAS
2pass案は多少工夫したらかなり速い

n ␣␣m ␣296␣ ␣301-1 ␣301-2 ␣303␣ ␣2pass
5k␣␣5 ␣ 0.5s ␣ 0.1s ␣ 0.5s ␣ 0.4s ␣ 0.1s
25k ␣5 ␣12.7s ␣ 2.5s ␣13.9s ␣11.1s ␣ 1.7s
100k␣5 ␣3m52s ␣49.3s ␣4m13s ␣3m26s ␣38.9s
1M* ␣6 ␣8h23m ␣2h50m ␣8h51m ␣6h43m ␣1h11m
*n=100万は1万サンプルの部分ループ500k≦r<510kから100倍

>>301
301(3): デフォルトの名無しさん [] 2024/03/06(水) 22:35:52.23 ID:lIZep5aT(1) AAS
>>282
C++
外部リンク:ideone.com
>>300の実行時間を分析すると、最も時間が掛かっているのは46〜と47行目だと判明した。
そこで配列ABの第1次元と第2次元を入れ替えてみると、n = 5000では変わらないが、
1万, 2万, 5万, 10万, 20万では35%前後高速になった。これは、改良前には第2次元の添字が
小さい要素に書き込みが集中しているため、改良後のように第1次元に入れ替えた方が
纏まったメモリ領域に書き込みが集中しキャッシュの効きが良くなるからだと考えられる。
一方、n = 100万で高速化しないのは、書き込み集中領域が大きすぎるからだろう。

外部リンク:ideone.com
n = 100万の場合にはr2の値によってデータを多数の列へ振り分けるのをやめ、列を1つにして、
その内部でr2の値により2種類に区分し、それぞれの内部で2種類にさらに区分し、…と再帰的に
区分していけば(要するにクイックソートの変形版)、1つの配列内での要素のスワップだけで済み、
キャッシュの効きが改善されるとの予想通り、n = 100万で実行速度は>>296より25%速くなった。
(原理的には>>300より非効率なのでn = 5000では>>300より当然遅い)
の296と301-2の比較記述と違う傾向があるのはキャッシュ階層の違いだと思う
2passは301-1に近いけど1pass目でのランダムアクセスサイズを落としながらも
誤判定率を低く抑える(0.2%~2%)工夫をするのがお楽しみだと思う
314: デフォルトの名無しさん [sage] 2024/03/31(日) 11:57:53.31 ID:enek7T1c(1/2) AAS
大幅に手直しした
特に前回数値が一部出てこない状態になっていたので色々と手動で最適化した
新しいアイディアを思いつかない限りはシングルスレッドでの限界に近いと思う

n m 301-1 303 2pass 2pass'
5k 5 0.1s 0.4s 0.1s 0.1s
25k 5 2.5s 11.1s 2.3s* 1.7s
100k 5 49.3s 3m26s 38.9s 27.7s
1M* 6 2h50m 6h43m 1h11m 48m10s
2M* 6 17h06m 28h27m 5h47m 3h13m
Max* 6 35h51m 51h23m 11h09m 5h47m

*前回>>309 2pass n=25kの再計測値
*n=1Mは部分ループ500k<=r<510kから100倍
*n=2Mは部分ループ500k<=r<505kから400倍
*Max:=2642245は3乗がUINT64に収まる最大
*n=Maxは部分ループ500k<=r<500k+3785から2642245/3785倍

ヒント含みの数値がこちら

n D1 D2 D3 = 5000 5001 5003 5009
false_positive = 23 / 5001 = 0.46%
total_t_pass1 = 64.220 ms 2.568 ns/iter
total_t_pass2 = 0.044 ms 0.381 ns/iter
real 0m0.097s
前次1-
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ AAサムネイル

ぬこの手 ぬこTOP 0.036s