- ベストアンサー
データコピー
unsigned short型の配列から別のunsigned short型の配列へ、データをコピーするときに、オーバーヘッドを少なく、いかに処理時間を高速にデータをコピーするかというお話です。 たとえば↓のようなデータがあったとします。 unsigned short a[100],b[100]; 配列aから配列bへどのようにしたら、高速にメモリコピーできるんでしょうか? memcopyを使用すると一番手っ取り早いのですが、ものすごくオーバーヘッドが高いと聞きます。memcopyを行うとどのような処理をしているのでしょうか? memcpyを使用しないなら、for文を使って for(i=0;i<100;i++){ a[i]=b[i]; } と私はしてしまいたいのですが、知人曰く、メモリアクセスには時間がかかるので避けたいとのことでした。 たとえば、aからbへの代入に一旦ポインタを使用して、double型でキャストして代入を行い、メモリアクセスの回数を減らして、for文のループも減らすという対策も出来るとおもいますが、一体どれが一番高速にaからbへデータをコピーできるのでしょうか? a[100],b[100]としましたが、サイズは任意です。大きい場合もあるし、小さい場合もあります。 なにか良いアイデア&memcopyの内部処理などを知っている方いましたら、教えてください。
- みんなの回答 (7)
- 専門家の回答
質問者が選んだベストアンサー
推測ですが、インテルの石では、中心部分は大体こんな感じではないですか。RISCチップやモトローラはわかりません。インテル一筋なもんで。 MOV EAX,CS MOV DS,EAX MOV ES,EAX POP SI POP DI POP ECX CLD REP MOVSB このソースの前後にCライブラリ特有の処理が必要になります。 ただ、関数のオーバーヘッドが気になるのでしたら、全体のアルゴリズムを見直して、データ転送ではなく、ポインタを使うようにしたほうがいいと思います。
その他の回答 (6)
- drmoreau
- ベストアンサー率41% (33/79)
インテル系の石の場合、アセンブラレベルで、メモリからメモリへのコピーをする命令は、ストリング命令、MOV命令しか用意されていないと思います。 関数のオーバーヘッドが気になるなら、インラインアセンブルしかないのでは。
お礼
ご回答、有難うございます。 相談を持ちかけてきた知人にそういってみます。 どうも私のレベルでは、無理みたいです・・・。 しかし、とても参考になりました。 ありがとうございました。
- notnot
- ベストアンサー率47% (4900/10358)
>実はこのプログラムは特定機器向け用に知人がC言語で作っている最中らしいです。 >先ほどその知人に聞いたところ、memcopyは使用できないとのことでした...。 memcopyも実装されてないような特定機器の話なら、こんな一般論的な質問をしても解決しないと思います。コンパイラの最適化能力もわからないし。具体的な機器名やコンパイラ名を書くと、それを知っている人なら回答できるかも。
お礼
ご回答、ありがとうございます。 実は知人からの相談なので、まったく環境がわかりません。 わかりましたら、お知らせしたいと思います。
- toysmith
- ベストアンサー率37% (570/1525)
『車輪を再発明してはいけない』 ソフトウェア工学ではよく言われる言葉ですが、その言葉には「効率を追い求めるだけのために標準ライブラリを再開発するな!」という意味が含まれます。 あえて車輪の再発明を望むならCPUのアーキテクチャ、CPUに内蔵されていないデータキャッシュのアルゴリズム、メモリBUSの仕様、仮想記憶のアルゴリズム、ページングデータセットのサイズなどなど考慮すべきポイントが山ほどあります。 少なくとも処理系依存の標準ライブラリはこれらを考慮して実装されているはずだからです。
お礼
ありがとうございます。 とりあえず、私のレベルではどうにもならなそうです。 でも、とても参考になりました。 どうもありがとうございました。
- uyama33
- ベストアンサー率30% (137/450)
アセンブラで書くのが早くなると言う話を 聞きました。 データの形がはっきり決まっているなら アセンブラの形の出力をつくり それから、一つ一つの演算の速度表と 回数を見て調整するのかな? 以前、私が書いたソフトと商売用に直して使っていた 友人がそのようなことをいっていました。 でも、私はmemcpy() を使います。 この時間が問題になるなら新しいコンピュータにすれば 速度の問題はすぐ解決するからです。 それに、簡単だし!!
お礼
ご回答どうもありがとうございます。 実はこのプログラムは特定機器向け用に知人がC言語で作っている最中らしいです。 先ほどその知人に聞いたところ、memcopyは使用できないとのことでした...。 マシーンのスペックも決まっているとのことです。 memcopyを使用せずに何か良いアイデアありませんか~? よろしくお願いします。
- taka_tetsu
- ベストアンサー率65% (1020/1553)
>memcopyを使用すると一番手っ取り早いのですが、ものすごくオーバーヘッドが高いと聞きます。 そうなんですか? できる限り高速化されてるはずなんですけどね。 ループなんかよりずっと速いはずなんですけど。 >memcopyを行うとどのような処理をしているのでしょうか? コンパイラ依存でしょうね。 VC++であれば、Cランタイムのソースも付属しているので中を確認することもできます。 おそらくアセンブラを使用していると思われますが。
お礼
ご回答どうもありがとうございます。 memcopyがオーバーヘッドが高いと知人が言っていたので、 本当かどうかは確かめていません。 しかし、それは依存するものだということを知れただけでも 大きな収穫です。どうもありがとうございました。
- toysmith
- ベストアンサー率37% (570/1525)
memcpyなどの関数は実装依存なのでアルゴリズムは想定してはいけません。 1バイトずつまじめにコピーしているかもしれないし、2~8バイト単位にコピーしているかもしれません。
お礼
ご回答どうもありがとうございます。 memcopyは実装依存なのですね。 あまり気にしないことにて、参考にしてみます。 ありがとうございました。
お礼
丁寧なご回答どうもありがとうございます。 実はこのプログラムは特定機器向け用に知人がC言語で作っている最中で 高速化をはかるために、ほとんどのアルゴリズムの改良を行なったらしいです。 で、残りはこの部分のみとのことでした...。 入出力は外部かららしく、それを自分のところのどうしてもポインタを使用せず、 メモリにコピーをしたいらしいです。 memcopyを使用せずに、高速にコピーできる方法で、 なにか良いアイデアありませんか~?? あったらどうぞよろしくお願いいたします。