C++相談室 part136
レス数が1000を超えています。これ以上書き込みはできません。
次スレを立てる時は本文の1行目に以下を追加して下さい。
!extend:on:vvvvv:1000:512
C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレにお願いします。
前スレ
C++相談室 part135
https://mevius.5ch.net/test/read.cgi/tech/1522495206/
このスレもよろしくね。
【初心者歓迎】C/C++室 Ver.102【環境依存OK】
http://mevius.5ch.net/test/read.cgi/tech/1509780815/
■長いソースを貼るときはここへ。■
http://codepad.org/
https://ideone.com/
[C++ FAQ]
https://isocpp.org/wiki/faq/
http://www.bohyoh.com/CandCPP/FAQ/ (日本語)
----- テンプレ ここまで -----
VIPQ2_EXTDAT: default:vvvvv:1000:512:----: EXT was configured HDDの一番外側15GB
セクタ直読みで60.1秒
平均 250MB/s でした
7200rpmの8TBのHDDです >>851の77.9秒はHDDの内側の方でfreadでの読み込み
どちらもHDDの限界と思います >>944
解析時間のほとんどが>>782のようなコードです
ちょっと変えましたが 改行を探す為だけにスキャンする必要はありませんし、コピーする必要もありません
ほとんどをしめる数値の行は
>>782の処理で区切りまでポインタが進みます >>951
ありがとうございます。楽しみにしています。
>>933,952,953
解析と読み込みを分けているんですね、8.6秒は解析で、読み込みがHDDのハード限界の60秒(高速な外側)、77.9秒(低速な内側)。
そこで >>851 の読み込み、解析合わせると78.1秒でほとんどがHDD律速ということか。
>>954,955
ご説明ありがとうございます。 >>782 の動作を調べてみます。
freadの扱いで質問なのですが、byte単位で取得すると最後尾が改行ではなく途中で終わることがあるので、
改行区切りになっているdata変数がだと思って、937に書いたコードでは、自分がわかる知識で考えて、
freadで読み込んだあとに改行のところまでfseekで戻しているんですが、この考え方はあっているのでしょうか? data変数がだと思って →×
data変数が必要だと思って →○ >>952
すみません、あと、 >>936 に書いているfgets版のコードだとどれくらいの速度が出ていますでしょうか?
fgetsで回したものと fread + >>782 のコードでどれくらいの比率になるのか気になりました。 MS製の金毘羅でfgets(), fgetc()を試す場合は、_CRT_DISABLE_PERFCRIT_LOCKS 必須で。 無能な働き者が書いた半角スクリプトなんて誰も走らせたくない >>956
読み込みの境目の処理方法はいくつかあります
A. 1行全体が連続してバッファに存在しなくてもいい作りにする
B. リングバッファ
C. fseekでファイルポインタを戻してから読み込む
D. あまりをmemcpyでバッファの先頭にコピーしてから読み込む
E. ほか
読み込み単位が大きければ C. or D. のコストは無視出来るので C. D. で
読みこみ単位が小さければ A. B. なども考える
といった感じかと思います
今回私は解析処理が簡単に作れて、HDDの読み込みに一切影響を与えない、D.で作りました >>958
fread
fgets
ReadFile
読み込みだけだとどれも78秒 >>959
ttp://ftp.tsukuba.wide.ad.jp/software/gcc/releases/gcc-8.1.0/gcc-8.1.0.tar.xz
これを使ってるので、まずはMSのオプションは関係なさそうです。
でもMSのコンパイラは早いという記事をこの前読んだのでそっちの方に乗り換えた方がいいのかな。
完成した後に両方テストして良好な方を検討しようと思います。
>>962,963
A,Bは難易度高そうですね。
Cは自分がやった手法のようですが、Dはポインタを戻す分の再取得が無いのでCより良さそうに見える。
Dを検討してみます。
fgetsもfreadも同じ時間ですか。
となるとfgets 13GB 17秒だから、そのレベルの速度は出るはずなのか。
今782のコードを調べて動作がわかってきました。
char演算で文字コードを数字の始点に移動させ9以下で数字以外(スペースor改行)を判定。
*10で桁を表現し、文字コードの番号で演算。(文字→数字変換していない!!)
このファイルで支配的な数字行が文字→数字変換が一度もないおかげですごく効きそう。
原理がわかるとなるほど!となるけど、1桁ずつ演算、文字コード演算は自分がやってたら絶対にたどり着かない発想です。 text/byte stream は異なる。
文字列はバイトじゃなく、テキスト
バイトは構造体など、構造が決まっているもの
改行区切りで、改行の位置が変わるものは、テキスト処理 通信データなどは、可変長構造体
ヘッダーなどは固定サイズで、データ部分は可変サイズ。
可変部分のサイズが、ヘッダーなどに書いてある >>969
C99なら規格化されたのでgcc拡張は要らなくなった C99の可変長配列はC++には取り入れられなかったし、
C11ではオプションに格下げされたんじゃなかったっけ?
年式でフラフラする機能の典型例のような記憶がある。 >>971
可変長配列(VLA)については、そのとおり
しかし >>970 >>969 で指しているのは、構造体内の 0 長配列メンバ、または C FAQ 2.6 >>971
VLA のことと誤解してないか?
ここで言ってる「可変長構造体」は構造体の最後の要素が不完全型であることを許すルールのことだと思う。
struct a {
int a;
int b[];
};
このとき sizeof(struct a) は要素 b を含まない大きさを返す。
malloc(sizeof(struct a)+(bの大きさとして確保したい大きさ)) とすれば b が可変長な構造体として使える。
このルールが出来る前 (C89) は仕様に沿ってこのようなことをしようと思うと
配列 b の大きさを便宜上 1 として指定しておく、
つまりは
struct a {
int a;
int b[1];
};
としておいて malloc のサイズ指定のときに要素一個分の大きさを差し引いて調整するようなことをしていた。 すまん、皆の言う通りだ。ちゃんと読めば
構造体の末尾メンバの0サイズ配列の話だと分かる流れだったのに、
なんでか裸の配列の要素数だと思いこんでしまった。 GCC拡張をしたとして
struct a {
int b[0];
};
のsizeof(a)はいくつなんじゃろうか… >>977
ゼロが返ってきたぞ。
ただし、 C/C++ におけるオブジェクトはメモリの一部を占有するものでありポインタで示せるものという要求があるので、
それと矛盾なく使うには色々と気を付けないといけないかもしれない。
ちなみに、クラスのメンバにストレージを割り当てないこと (要するにサイズゼロのオブジェクト) を許す [[no_unique_address]] という属性が C++20 で追加されてる。 そんなクソみたいな使い方しかされない機能入れるなよ。。 複数回allocateを抑制するための機能(関数)はc++にもたくさんあるじゃない >>979
非staticなメンバを一つも持たない上、そのクラスのポインタを扱わない(=多態性を必要としない)のに
継承したりメンバとして持ったときに1バイト追加されるのがうざいからだろ >>978
ええー!!!
struct c {
};
のsizeof(c)は1だった(と思った!)が!! 最適なプログラムを書く必要のない立場の雑魚は黙ってろよw >>981
static なメンバしかない、しかもポリモルフィズムしない(interfaceな使い方でもない)
ってそもそも継承するのが設計として間違いじゃねーの? c++つかってるとロジックやアルゴリズムなどの本来の目的より
こういう横道にそれた話題ばかりになることが多い
手段が目的化するので困る 関心の集中の先はプログラムで実現できることになるべきだけど
c++はそっちより言語自信や仕様や実装に目が向く
時間が無駄に費やされやすい 最適なプログラムを書くのもC++の目的だ
ロジック以外のことに目をそらしたいなら他の言語を使え c++は幅広い書き方ができてしまうのが一番困ったところ
10年前のコードが完全に動いてるにも拘わらずゴミに見えてしまう >>984
非staticなメンバが無い、ってのはメンバ変数ね(非staticなメンバ関数はあっても関係ない、つまりインターフェースも含む linuxと聞いてた(>>743)のになんでMSのコンパイラの話がでてんねんと
まず実機でコレ走らせて試験をしなさい
@ 下のソースをコンパイルしてbaka_testという名前の実行オブジェクトをつくりなさい
linuxなら↓こっち
https://ideone.com/e9iA5m
windowsなら↓こっち
https://ideone.com/D4T1zh
A で、こんな試験をする
https://ideone.com/82BnFZ
ちなみにwindowsはバッファサイズを
セクタバイト数の倍数でないとちゃんと動作しない
それはwindowsの仕様だからな(メモリアドレスはmallocで返ってくる先頭のポインタオフセットで問題ないことは分かってる)
バッファサイズを何バイトにするのが読みこみで効果的か
決めたほうがいい
試験結果をちゃんと報告するようにな
あとOSは64bitでいいんだな
それによっても話がかわってくる ちなみにwindowsでopenとかread使うのはクルクルパーだからな
msのランタイムがウンコなのは有名だからな
msウンコランタイムのopenでCreateFile呼び出してる
msウンコランタイムのfopenでopen呼び出してる
msウンコランタイムのreadでReadFile呼び出してる
msウンコランタイムのfgetsやfreadでread呼び出してる
わかった? >>993
ありがとうございます。
g++ -o baka_test $file_name
echo 512,`./baka_test $input 512` > baka_result.txt
echo 1024,`./baka_test $input 1024` >> baka_result.txt
〜
上記を13GBのファイルで試したら下記結果が出ました。
512,13
1024,7
2048,5
4096,3
8192,2
16384,2
32768,2
65536,2
131072,1
262144,3
524288,2
1048576,2
2097152,2
4194304,2
8388608,2
16777216,3
33554432,2
67108864,3
134217728,3
268435456,3
536870912,3
1073741824,3 これは一度に読み込むサイズは4KBを超えると速度に影響はなく、
>>962 のC,Dパターンの場合だと、最低1行分のバッファが必要なので、
その場合、一行のバイト数のMAX値で決めれば良い。
ということでしょうか? どんだけ速いHDDやねん。。。
すでにキャッシュされてんのか
その13とか7とか5とかいう数字は
ディスク読みこみ(ディスクの内容をバッファにコピー)にかかった時間は秒だぞ
ちゃんとコード書いてmsecにして計測したほうがよかったのかもな
暇だったら、シェルで精度の高い計測値だせるように工夫しなさい
数十秒はかかると思ってたからmsecなんか考えてもなかったわ
で、実機のOSは64ビットでいいのか
ここ結構重要だからな すみません忘れてましたlinux 64bitです。
> 128Kで2秒かからない
これのことですね。 →131072,1
昨日の夜(今日の朝5時)までやって >>962 のCパターンでようやく一通りファイルを
読み込めるようになりましたが、やはり速度が出ていません。
13GBファイルで確認
fgetsのみ解析なし →17秒
freadで各文字列解析、数値行の演算を行ったもの →1分超え
コード書いてて気になる箇所がいくつかあるので質問しようと思ったけどもう1000になりますね。
次スレで質問させてもらいます。 なんかよく分かってもらえてないようだが
この値はブロックで読みこむ固定のバッファリングサイズ
1行分とか関係ない
プログラムではきっと
バッファリングされたメモリを解析することになる
とりあえず今回は、必ず128K単位で読みこむ
128K単位のメモリを
正直もっと増やしてもいいとは思う
あととりあえず行の最大バイト数は256バイトで十分でいいや このスレッドは1000を超えました。
新しいスレッドを立ててください。
life time: 36日 16時間 10分 3秒 5ちゃんねるの運営はプレミアム会員の皆さまに支えられています。
運営にご協力お願いいたします。
───────────────────
《プレミアム会員の主な特典》
★ 5ちゃんねる専用ブラウザからの広告除去
★ 5ちゃんねるの過去ログを取得
★ 書き込み規制の緩和
───────────────────
会員登録には個人情報は一切必要ありません。
月300円から匿名でご購入いただけます。
▼ プレミアム会員登録はこちら ▼
https://premium.5ch.net/
▼ 浪人ログインはこちら ▼
https://login.5ch.net/login.php レス数が1000を超えています。これ以上書き込みはできません。