PC間のファイルのコピーを高速化する方法

[戻る]
QQQ 2013/02/15(金) 11:09:19
1台のPCから 3台のPCに 2000個程のデータをそれぞれにコピーを行っています。
それぞれ別々のデータ(計6000個)で ファイルサイズは大小さまざまで数100Mから数K
まであります。今までは 単にCopyFileを使い、ひとつずつコピーを行っておりました
がコピーに5分程度かかってしまいます。
それで 並列に処理させたらいいと思い、3台のPC用にそれぞれスレッド作成し、
CopyFileでコピーしましたが 早いときは3分程度で 終わるのですが 遅い場合は 10
分程度かかり、速さが安定しません。

このような 複数のPCに 大量のデータを コピーする場合は
どのようにすれば早くなりますか?

環境は
XP64bit
VS2008 です。 

Ryo 2013/02/15(金) 12:09:04
処理を並列にしても、ハード(HDDなど)は並列に動くようにできてないものなら
無駄なランダムアクセスが発生し時間が不安定になるのは仕方ない。
2000個ずつのデータを事前に連結ファイルにして1個(計3個)にしておくか
ハード面を高速のモノに取り換えるぐらいしかないでしょう

QQQ 2013/02/15(金) 13:22:02
回答 ありがとうございます。
知識がなくてすみません。
連結ファイルにするというのは どうゆうことでしょうか?
圧縮して1つにするという意味でしょうか?
(容量的にも すべてで 15G以上はあります。)
ハード面を高速なものにするというのは
SSDを使うみたいなことでしょうか?
ご教授願います。

tetrapod 2013/02/15(金) 14:29:57
この手の「性能」の話は、どこがネックになっているかの測定から。
・サーバ側の記憶装置(ハードディスク)が遅い?
・サーバクライアント間のネットワークが遅い?
・クライアント側の記憶装置(ハードディスク)が遅い?
・上記以外の何か(たとえばウイルス対策ソフトのリアルタイムスキャン)が遅い?

すでに速いところをさらに速くしても効果はない。
遅いのがハードディスクであると確定したのならば SSD にするのは意味があるが
そうではないのなら無駄な投資。

仲澤@失業者 2013/02/15(金) 18:06:48
え〜と、回答ではありません。単なる感想です。すみません。

こういった「サーバーがお配りする」仕組みって、やや不利なんですよね。
「クライアントが持ってくぞ」型にするとやや改善すると思うんですけど、
いまさら仕組みを変えるわけにはいかないでしょうね(vv;)。

あうあう 2013/02/16(土) 01:32:28
1.同じ物を3ヵ所にコピーするなら1度だけメモリに読み込んで
 メモリ内容をコピーした方が早いのでは?
2.結構管理が面倒くさいですがある程度のメモリを確保して
 複数ファイルを一気に読み込んで各PCに書き込む

#2番目はもうフリーソフトでありますね
#FireFileCioyとか。検索すると仕組みも書いてあります。

組み合わせれば早くなるのでは?

 

あうあう 2013/02/16(土) 01:36:30
訂正
#FireFileCioyとか。検索すると仕組みも書いてあります。

Fire File Copy
http://www.k3.dion.ne.jp/~kitt/pc/sw/ffc/

あうあう 2013/02/16(土) 01:44:34
大事なこと核の忘れてた
1度読み込んだファイルをメモリにためて各スレッドで
共有して書き込めば1/3とはいかないまでも少しは早くなるんじゃないかと。

ITO 2013/02/16(土) 15:45:06
うーーん、
 1. ソフトを考える前に、実際にコピーをするファイルを作ってエクスプローラを使って
  コピーしてみる。
 2.時間を測定してみる。
  僕が考えるに、どんなに速くコピーするソフトを作ってもエクスプローラを使って
 コピーするのと比べるとあまり速くなっていないと思います。
 速くコピーすることを考えるよりも、スレッドを使い、2000個のファイルをいかに
 効率よくまとめてコピーするかを考えた方がいいと思います。
>それで 並列に処理させたらいいと思い、3台のPC用にそれぞれスレッド作成し、
>CopyFileでコピーしましたが 早いときは3分程度で 終わるのですが 遅い場合は 
>10分程度かかり、速さが安定しません。
タイマーやイベント等の同期オブジェクトをうまく使って速さを安定させることを
考えたほうがいいと思います。

みい 2013/02/16(土) 18:34:25
ちなみに3台のPCはHUBを介して1つのポートでつながっていますか?
それとも1ポートずつ直結させていますか?
もしHUB経由の1ポートだったらポート増設して1台ずつ直結させたら
回線が分かれるので多少は早くなるはず(仕様/環境が許せばですが)

QQQ 2013/02/18(月) 10:34:48
皆様 回答ありがとうございます。

あうあう様 :
各PCにコピーするファイルは別々なので 提案していただいたやり方では やりにくい
とは思いますが そのような方向を当方も考えておりました。
実際 自分が試したやり方では スレッド化して 読み込み書き込みがぶつからないよ
うにしたとき(CopyFileを使っているため書き込み読み込みは分離していなく その部
分だけをmutexで止めた) LANの稼働率(タスクマネージャーのネットワークで出るや
つ)が 上がり下がりありますが 最大60%ぐらいで安定しており、書き込みをぶつか
るぶつからないを考慮せず、ただのスレットだけで 行った場合は ほぼ100%になるの
ですが 安定感がなく、次に同じ動作をさせると、数十秒100近くになったあと 2,30%
に落ちてしまいます。
Fire File Copyなどの別ソフトというのは これまでに使ったことがなく、やり方考え
てみます。

ITO様 :
エクスプローラで ソフトと同じように ファイルのコピーを3つ同時に行うと
はじめの 数十秒間は 早いのですが 途中から 遅くなり 10分以上かかりました。
LANの稼働状況で行くと 上記のスレッドの 書き込み読み込みが ぶつかるのを考
慮しないパターンと同じ感じです。
この場合 HDDのアクセスが 怪しいのでしょうか?

みい様 :
1つのポートでHUBにつながっています。
すみません。現段階でハード的には変えにくいです。

ITO 2013/02/18(月) 11:26:33
>この場合 HDDのアクセスが 怪しいのでしょうか?
うーーん、
 ファイルが2000個もあり、15GBもあるのだからと思います。
ウインドウズはマルチタスクOSですが、マウス・キーボート・システム関連の処理を約200mS
間隔でチェックします。これは通常最優先で処理されます。

> 早いときは3分程度で 終わるのですが 遅い場合は 10分程度かかり、速さが安定
しません。
 容量の小さいファイルをまとめて先にコピーして後から大容量のファイルをまとめて
コピーするとかすると3分程度で一定になるってことはないでしょうか?
あくまで推測です。
 エクスプローラは安全策で10分以上かかるようにしているのだと思います。

QQQ 2013/02/19(火) 17:54:30
容量は1.5G程度です。
間違えておりました。
すみません。

ITO 2013/02/19(火) 19:08:10
>容量は1.5G程度です。
 ファイル数は変わらないとなるとあとは2000あるファイルをうまく選択して、
効率よくコピーすることが大切だと思います。

> 早いときは3分程度で 終わるのですが 遅い場合は 10分程度かかり、速さが安定
しません。
3分が限度と考えて、
  スレッドを活用して3分ぐらいで処理時間が維持できるようにする
のがいいと思います。

仲澤@失業者 2013/02/20(水) 09:57:35
>容量は1.5G程度です。

8.33[MByte/s]は、昨今ではかなり遅いネットワークと言えるかもしれません。
このあたりにヒントがあるような気がします。

bun 2013/02/21(木) 09:37:58
参考までに、ファイルコピーだけが目的なら、Windowsのファイル共有より、
FTPの方が速いです。

サーバ側にはIIS(Internet Information Server : OS種によっては標準添付)
を入れるのが手っ取り早いです。LinuxサーバならApacheなど。
フリーソフトのFTPサーバもたくさんあります。

クライアント側アプリは、MFCベースなら、以下のHPに詳しく解説があります。
  http://www.g-ishihara.com/mfc_pt_01.htm

AR 2013/02/22(金) 13:30:24
 まず、どの程度の速度を目標値におくか、が明確にならないと性能上げのチューニング
は成果が上がりません。
 どこがボトルネックになってるのかを測定し、理論限界値はいくつなのかを計算するこ
とから始められるのが良いと思います。
 ネットワーク越しのファイルのコピーだと、考えるべき内容が多いので、いくつか分割
して考えると良いでしょう。

 たとえば、すでに述べられていますがHUBとの構成や、ネットワークの接続速度を上げ
るのは、ハードウェア/環境設定など、アルゴリズムとは無関係ですが、大幅に性能が上
がります。

 次に、アルゴリズム的な話をすると、ファイルコピーをマルチスレッド化すると、一般
的にファイルコピー速度は低下します。
 エクスプローラーでも同じなので、検証してみてください。
 ですから、高速化のためにマルチスレッド化・・・というアプローチは間違いです。
 HDDのベンチマークを見る機会があると思いますが、シーケンシャルな読み書きと、ラ
ンダム読み書きで速度が桁違いなのはご理解いただけると思いますが、マルチスレッド化
すると、必然的にランダムアクセスを多用することになる事が原因です。
 ストライピングなどのハード構成でもない限り、HDDは基本的にシングルスレッドで扱
うのが最も効率的です。

 シングルスレッドでファイルコピーを行う場合は、コピーの際の読み/書きを行うバッ
ファを大きくとる事がもっとも効率的に処理を行えます。
 最近のエクスプローラは知りませんが、NT4の頃はこのバッファサイズが4KBちょいしか
ありませんでした。
 4KBごとに、読み/書き/読み/書き/読み/書きと繰り返してたわけです。
 FireFileCopyなどは、このバッファサイズをメガバイト単位で取得することで、高速化
しているはずです。

 余談ですがFTPが速いってのは、16KBだったか64KBだったかうろ覚えですがFTPのバッ
ファが大きいことによるものと思います。

AR 2013/02/22(金) 13:38:13
一応、補足です。
頻繁に読み書きを繰り返すと遅くなる理由は、
(ヘッド動かす)読み/(ヘッド動かす)書き/(ヘッド動かす)読み/(ヘッド動かす)書き
のようになり、HDDの回転を待つシークタイムが発生するためです。
連続領域に、続けて読み/書きできれば高速化できるのは、必然といえるでしょう。

今、使えるか情報か分かりませんが、MS社の説明文がありましたので紹介しておきます。
http://support.microsoft.com/kb/223140/ja?wa=wsignin1.0

ITO 2013/02/23(土) 13:13:44
ん?
もしかして、
1台のPC、データ提供側のPCもXPですか?
ピアーツーラン接続ですか?
たぶん、サーバーOSを使いドメイン接続で使わないと3台のPCの状況でLANのスピードが
変わってしまうと思います。
重たい処理で遅くなっているPCがあるとそのPCにあわせるようになるので、結果速度
がおそくなると思います。
FTPサーバのフリーソフトがあるので、安く済ませるのならFTP接続かなと思います。
ただその場合はFTP接続でソフトを組まないとだめです。

ITO 2013/02/23(土) 13:15:42
修正
ピアーツーラン接続→ピアーツーピア接続
です。

QQQ 2013/02/28(木) 11:22:16
[[解決]]
一応 ある程度成果が出ましたので 書いておきます。
私がした方法は CopyFileを freadとfwriteに換え、メモリを毎回確保せずに、
最初に大き目のメモリを取って流用する方法です。
おそらく 2000ものファイルを 並列(3個)にCopyFileをすることで 
メモリの確保が乱発し何かよくないことが起こっていたのでしょう。
(私の知識ではこれぐらいしかわかりません。)
現状 fwriteで待っている感があるのですが これについては
LANがボトルネックになっているので...

私の知識が少なく すべての助言をいかせきれず
こんな単純な方法で 解決とするのは 心苦しいですが
皆様 いろいろな助言をくださりありがとうございました。

古いスレッドには追加発言できません。