ファイル入出力APIで確保するバッファーの容量について – プログラミング – Home

ファイル入出力APIで確保するバッファ...
 
通知
すべてクリア

ファイル入出力APIで確保するバッファーの容量について


よっぴぃ
 よっぴぃ
(@よっぴぃ)
ゲスト
結合: 13年前
投稿: 5
Topic starter  

readfile(),writefile() などのファイル入出力のAPIで
確保するバッファーサイズは、どのようなサイズがいいのでしょうか?
コピーを高速化したい場合は、可能な限り大きく確保すればよいのでしょうか?


引用解決済
トピックタグ
しま
 しま
(@しま)
ゲスト
結合: 18年前
投稿: 123
 

開発環境について書かいて下さい。
開発環境がわからないと適切な回答が書けないことがあります。

OSのバージョン、コンパイラーのバージョン(VC 6.0 など)、
MFC を使う/使わない、SDKのみ、managed なC++など

>確保するバッファーサイズは、どのようなサイズがいいのでしょうか?
「必要なだけ確保する」が私の考えです。
ファイルを全部読み込むことが可能な場合は全部読み込むこともあります。
一行毎に処理をする場合で、一行の長さの上限が決まっている場合はその
上限にするだろうし。処理によって違ってくると思いますけど、どうでしょう?

>コピーを高速化したい場合は、可能な限り大きく確保すればよいのでしょうか?
それもどうでしょう。コピー対象が小さい場合は可能な限り大きくすると
使いもしない記憶領域を確保することになるような気がします。

なので状況に応じて領域の確保の考え方はいろいろだと思います。


返信引用
よっぴぃ
 よっぴぃ
(@よっぴぃ)
ゲスト
結合: 13年前
投稿: 5
Topic starter  

開発環境は、VC++2005,2008,2010 MFC またはSDKのみの汎用的です。
コピー対象とするファイルは、動画ファイルなどの数GBの大型バイナリーファイルで、
windowsで、ドロップしてコピーすると、残り200分などと表示させるサイズの
ものを想定してください。よろしくお願いします。


返信引用
しま
 しま
(@しま)
ゲスト
結合: 18年前
投稿: 123
 

>動画ファイルなどの数GBの大型バイナリーファイルで、
>windowsで、ドロップしてコピーすると、残り200分などと表示させるサイズの
>ものを想定してください。

自分のアプリケーションだけが動く場合なら確保できる上限まで取ってしまうことも
問題ないでしょう
ただ、主記憶の容量以上に確保してもWindows は(32/64共に)仮想記憶なので、
ページングの対象が増えるだけですから、コピーの速度が早くなる方向に効くとは
思えません。
もっとも、ちょこまか読書きするよりはドンと大きく読書きする方がコピー時間
が短くなるとは思います。4Gバイト確保したからといって主記憶で 4G バイト
確保できる保証がない以上(Win32 はアプリケーションの記憶空間は 2G もしくは
3G が上限です)やたらでかくとってもコピー速度にとって意味があるかどうか
疑問です。
こういう効率の問題は実際に試してみるのが一番です。


返信引用
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

まあ今でもメモリ実装量 512MB のマシンもいっぱいあるわけで。
コピー用のバッファに実記憶より大きなサイズを取得するなど無意味。

バッファサイズとしてはディスクのセクタサイズの整数倍がいいだろうし、
いまどき AFT な 4KB セクタサイズのディスクも普及しているし、
64KB とか 128KB 程度に抑えておくのが良いんではないかな・・・と。

ちなみに CopyFileEx を使わないのはなぜ?
ReadFile + WriteFile だけだとタイムスタンプなど副次情報はコピーされないし
代替ストリームもコピーされない。
残りバイト数なんかも自動でわかるし手作りするよりずっといいと思うが。


返信引用
PATIO
(@patio)
Famed Member
結合: 3年前
投稿: 2660
 

共通関数的な物を作成しようとしているのであれば、
tetrapodさんが書かれているようにCopyFileExを使わないのはなぜと言う話になるかと。
使えない理由があるのであれば、それも提示しておかないと話が繋がりません。

既に皆さんが書かれているようにとにかく大きくすれば良いという話ではありません。
あと、ユーザーが使っている他のアプリへの影響などを考えると結果的に傍迷惑な
関数になりかねません。実際の話、こうすれば良いと言う銀の弾丸はありませんから
使用される環境に合わせてチューニングするか、共通関数と言う位置付けなら
なるべく効率が良くて利用環境を縛らない容量を自分で探ると言う話になると思います。


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

うーーん、
  コピーの高速化をしたいのなら、データーの欠落を防ぎながらマルチタスク処理
 を行なう。
だと思うのですが、どうでしょうか?
WiNDOW7になって、64ビット版を使う人が増えているかに思います。
今は、メモリーの確保をして、高速化を図る時ではないと思います。


返信引用
よっぴぃ
 よっぴぃ
(@よっぴぃ)
ゲスト
結合: 13年前
投稿: 5
Topic starter  

ありがとうございます。
readfile(),writefile()を使用したい理由は、「**%完了」など、途中で進行状況を把握
したいためです。
マルチスレットにするのは、直観的ですが、処理速度速度を考えると、CPUの処理より
も、ハードディスクの書込速度のほうが影響が大きそうなので、どうかなとも思います
が、いかがでしょう。

 


返信引用
瀬戸っぷ
 瀬戸っぷ
(@瀬戸っぷ)
ゲスト
結合: 18年前
投稿: 178
 

>readfile(),writefile()を使用したい理由は、「**%完了」など、途中で進行状況を把握
>したいためです。

で、皆さんが掲示しているCopyFileEx()は調べてもいない…ということでしょうか?
CopyFileEx()でコールバック関数が指定できますが、そこに
・バイト単位の総ファイルサイズ
・転送された総バイト数
とか渡されますが…。


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

> マルチスレットにするのは、直観的ですが、処理速度速度を考えると、
> CPUの処理よりも、ハードディスクの書込速度のほうが影響が大きそうなので、
> どうかなとも思います
> が、いかがでしょう。

 コピーした後、すぐに何か処理があるというなら、
   最終書き込みは後にしてメモリーに書き込んでおく。
 というのは分かりますが、GB単位あるとなるとそれも現実的でないですね。
 
 ハードディスクの速度の問題なら、SSD限定にしてもらうなど、考えれば
  手段もあるのでは?
 
 FireFileCopyやFastCopyなどフリーで高速コピーできるツールもあるみたいです。
 実際に使って見ることもいいと思います。


返信引用
浩
 浩
(@浩)
ゲスト
結合: 13年前
投稿: 2
 

CopyFileExは、処理自体はOS任せですから
質問者の意図にそぐあないですよね。。

セクタサイズや、API発行毎の処理のトロさに左右されますから
数K~数MB程度の間で実験してみるのが一番かと。

あとFastCopyはソースも公開されているので
参考にしてみてはどうでしょうか。


返信引用
PATIO
(@patio)
Famed Member
結合: 3年前
投稿: 2660
 

処理がOS任せであったとしても性能的に十分で機能的にもOKなら
選択肢としてはありだと思いますよ。
実際に試してみて自分の要件に合わなければ、候補から外せば良いだけですし。
質問時の内容に関しても漠然としているのでそもそもCopyFileExでは駄目なのかが
わかりません。

既に試していて性能的にだめという結論が出ているなら話は別ですが、
はっきり結論が出ていないのであれば、試してみる必要はあると思いますよ。

性能的、機能的に満足できないのであれば、自作するのも一つの方法なので
その場合は既に紹介されているようなアプリのソースを参考にさせてもらうとか
しても良いと思います。
汎用的に早くて利用環境を選ばないような物を目標にするのであれば、
かなり試行錯誤が必要そうですね。
試してみるのも面白そうではありますけれど。


返信引用
みい
 みい
(@みい)
ゲスト
結合: 22年前
投稿: 65
 

CopyFileExのサンプルが載ってるHP↓
http://d.hatena.ne.jp/s-kita/20100619/1276914572
リンク先にサンプルコードと実行結果(コピー途中のサイズ取得)が載っています。


返信引用
bun
 bun
(@bun)
ゲスト
結合: 24年前
投稿: 761
 

遅くなりましたが、この件は重要な考慮点があります。
以前に試してみた結果、

1) バッファを1Byte → まじで遅い
2) バッファを4KByte → エクスプローラ並みの速さ
3) バッファを100MByte → 4KByteと大して変わらない

そして、重要なのはネットワークを介してファイルを読み書きする場合です。
あまりバッファサイズを大きくすると、タイムアウトが発生するようで、
読み書きに失敗します。
再試行すると、どういう原理なのか成功しますが、タイムアウトを回避するの
が大変です。
いろいろ試しましたが、数KByte程度が良さそうです。


返信引用
PATIO
(@patio)
Famed Member
結合: 3年前
投稿: 2660
 

ネットワーク越しになると実は話が変わってくるって部分は
見落としがちかもしれませんね。
実際には別のPC上のパスを指定されるだけなので同じインターフェイスで
ローカルのコピーもネットワーク越しのコピーも出来てしまいます。
内部的にネットワーク越しでないかどうかのチェックでもしない限りは
同じロジックで動いてしまいますからね。

bunさんの指摘も考慮に入れると同じロジックで行くなら
バッファサイズをむやみやたらと大きくしても処理スピードは
上がらないと言う事になりますね。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました