- PR -

8/16bit長数値データの演算効率

1
投稿者投稿内容
ひろし
ぬし
会議室デビュー日: 2002/09/16
投稿数: 390
お住まい・勤務地: 兵庫県
投稿日時: 2003-07-28 11:39
リアルタイム処理で複雑な数値計算(巨大な行列計算等)をする場合、効率を考慮する必要があります。ここでいう効率とは@CPU負荷(演算速度)A資源効率(メモリの消費量)を想定しています。C#で数値計算の効率を追求する場合、どのようなルールが適用されるのでしょうか?


★演算速度についての疑問
背景
「Pentium-4は32bitCPUなので32bit演算(int,float等)を最も効率良く処理でき
る」と記述している本があります。この記述を文字どうり信用して良いのでしょ
うか?つまり、メモリ消費量が問題にならない場合、あらかじめ変数の取りうる範囲
が8bit(byte)あるいは16bit(short等)範囲に収まることが明白であっても効率最
優先なら無条件にintやfloatを使うべきという理屈が成り立ちます。
しかし、一般的に演算精度が高くなればなるほど演算負荷が高くなるという理屈
も成り立ちます。C#の場合、Pentium-4の上にNetFrameworkがかぶさっているので
更に複雑です。加減算より演算負荷が高い乗除算やSystem.Mathの関数を参照する
場合、まめにbyte,shortで宣言したほうが良いのかそれとも常にintで宣言しよう
か迷ってしまいます。

Q1-1.
乗除算およびSystem.Math関数を使う場合、CPU負荷を優先する場合intを使うべきか?
それともbyte,shortを使うべきか?
(例 short*shortとint*intの比較)

Q1-2.
異なった型同士の演算は避けて同一型どうしの演算にすべきか?
(例 short*intとint*intの比較,float*intとfloat*floatの比較)
コンパイラが常に演算前に高位の型に変換(例 short→int)してから演算しているなら
shortやbyteを混ぜると変換の分オーバヘッドがかかってしまうことになります。
そうでなくて異なった型どうしでも最適な演算ロジックが個別に用意されているなら
もしかするとshort*intのほうがint*intより高速である可能性があるはずです。
実際どう実装されているのでしょうか?

★メモリ消費量についての疑問
Q2-1.bool型は論理的には1bitしか消費しないはずですが、CPUの処理効率を考慮して
実際は8bitあるいは16bit長の領域のうち下位の1bitを占有するかたちで実装する
処理系も一般的だと思います。C#(NetFramework)の場合、bool型はどう実装されている
のでしょうか?

Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2003-07-28 12:49
引用:

ひろしさんの書き込み (2003-07-28 11:39) より:

Q1-1.
乗除算およびSystem.Math関数を使う場合、CPU負荷を優先する場合intを使うべきか?
それともbyte,shortを使うべきか?
(例 short*shortとint*intの比較)



 コンパイラが最適化を行ってくれますが、乗除を行うところを和差に置き換える方が早くはなるでしょう。2倍/半分にするところをビットシフトに置き換えたり・・・。そういえば大学の講義で、乗算は2倍と足し算に置き換えろ、みたいなことが
例:x * 3→x * 2 + x
ただ、最近のコンパイラは賢いので、これくらいの最適化はしてくれていたと思います。

 それよりも、結局はPentiumの機械語に置き換わるのですから、ニーモニック表を見て、Pentium4の命令にどんなものがあるか調べてみては如何でしょうか。1命令に収まるような演算、例えば乗除算をする命令があれば、乗除算について考える必要はなくなるでしょう。
 その中で32ビット未満の演算をする命令があるなら、shortなどを使えばよいし、内なら32ビットで演算する方が速いでしょう。また64ビットの演算をする命令もあったと思います(マルチメディア系)。
 ただ、これらの命令を「本当に使おうと思ったら」、アセンブラで書くか、インテルのコンパイラを使用する必要があると思います。.NETは結局インタープリターみたいな所があるので、ネイティブに置き換えられるものを使わないと、恩恵にあずかれないのではないでしょうか。その意味で、一連のご質問はナンセンスかと思います。
mei
大ベテラン
会議室デビュー日: 2003/04/08
投稿数: 114
投稿日時: 2003-07-28 13:02
こんにちは、meiです。

C#におけるリアルタイムシステムについてですが、
http://www.computer.org/software/homepage/2003/s1lap_1.htm
↑この辺が参考になると思います。

double vs floatについては、こちらを。
http://www.pro.or.jp/~fuji/mybooks/cdiag/cdiag.4.4.html

ちょっと時間がないので、簡単ですが・・・
なな
ぬし
会議室デビュー日: 2003/06/22
投稿数: 659
お住まい・勤務地: 愛知県
投稿日時: 2003-07-28 13:05
> リアルタイム処理で複雑な数値計算(巨大な行列計算等)をする場合

互換性を無視して効率を優先するならば...
数値計算部をC++で実装でしょう。

で、混合モードで表示して効率を確認するのが良いと思います。
ひろし
ぬし
会議室デビュー日: 2002/09/16
投稿数: 390
お住まい・勤務地: 兵庫県
投稿日時: 2003-07-28 13:31
返答ありがとうございます。おっしゃる通りだと思います。
製造業の技術者なのであんまり長々C#のIDEに向かっていると周囲から冷たい
視線で「趣味の世界で遊んでいる」と言われかねないので、恥も外聞も無く
この会議室に投稿している次第です。(本当は四の五の言わず自分でも色々
実験してみたいのですけどね)私もMS-C Ver6の頃まではコンパイルして逆ASMして
解析していました。今は時間が…ありません。

余談ですが、昔のスーパーコンピュータ全盛時代の技術計算用のコンパイラは最適化ロジックに
様々な工夫を凝らしていて(ロジックの変更を含む広域最適化までしてくれた!)
非常に賢いものもありましたが、C#のコンパイラが最適化面で賢いかどうかはあやし
いと思っています。
なな
ぬし
会議室デビュー日: 2003/06/22
投稿数: 659
お住まい・勤務地: 愛知県
投稿日時: 2003-07-29 08:33
> 製造業の技術者なのであんまり長々C#のIDEに向かっていると周囲から冷たい
> 視線で「趣味の世界で遊んでいる」と言われかねないので

気持ちわかります。
わたしも製造業なので...。

現実的には...
・とりあえず、C#やVB.NETで作ってみる
・パフォーマンスに難があれば、部分的にC++で実装する
・まだパフォーマンスに難があれば、速いPCを購入
といったところでしょうね。
1

スキルアップ/キャリアアップ(JOB@IT)