C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

四則演算の計算コストの比較

[トピック内 16 記事 (1 - 16 表示)]  << 0 >>

■93405 / inTopicNo.1)  四則演算の計算コストの比較
  
□投稿者/ ねと (1回)-(2019/12/10(Tue) 16:21:22)

分類:[.NET 全般] 

四則演算の計算コストを知りたいのですが、
以前、VBAで比較した時には、

足し算 = 引き算 < かけ算 < 割り算

という順番で計算コストがかかることが分かりました。

一方で、VB.NETを使ってどうように計算コストを比較してみると


足し算 = 引き算 = かけ算 < 割り算


であることが分かりました。

ここで疑問なのは、
普通に考えると足し算よりもかけ算の方が計算時間がかかるはずですが、
なぜ足し算とかけ算の計算コストが同じなのでしょうか?


たまたま、VBAにおいて、足し算よりもかけ算の方が時間がかかっただけであって
他の言語C++などにおいても足し算とかけ算が同じなのは一般的なのでしょうか?

以下が比較を行ったソースコードです。
意外と検索しても情報が見つかりませんでした。


        Dim ValDbl As Double = 20

        Dim ResultDbl As Double


        Dim sw2 As New Stopwatch
        sw2.Restart()

        '空1473 msec
        For i = 1 To 1000000000

            '2642 msec
            '  ResultDbl += ValDbl

            ' 2672 msec
            ' ResultDbl -= ValDbl

            '2668 msec
            ' ResultDbl *= ValDbl

            ' 5228 msec
            ResultDbl /= ValDbl

        Next


        Dim hhh = sw2.ElapsedMilliseconds

引用返信 編集キー/
■93407 / inTopicNo.2)  Re[1]: 四則演算の計算コストの比較
□投稿者/ PANG (1回)-(2019/12/10(Tue) 16:57:38)
No93405 (ねと さん) に返信
> たまたま、VBAにおいて、足し算よりもかけ算の方が時間がかかっただけであって
> 他の言語C++などにおいても足し算とかけ算が同じなのは一般的なのでしょうか?

C++でも同じのようです。
http://www001.upp.so-net.ne.jp/y_yutaka/labo/math_algo/calcbench.html
引用返信 編集キー/
■93408 / inTopicNo.3)  Re[1]: 四則演算の計算コストの比較
□投稿者/ はまぐり (81回)-(2019/12/10(Tue) 16:59:04)
No93405 (ねと さん) に返信
Java
https://paiza.io/projects/H0uf3k1mY-k-nszv34Gl4w

add:122
sub:122
mul:122
div:386

同じ結果になりました
CPUは割り算がにがてぽ
引用返信 編集キー/
■93409 / inTopicNo.4)  Re[2]: 四則演算の計算コストの比較
□投稿者/ ねと (2回)-(2019/12/10(Tue) 17:13:11)
ありがとうございます。
足し算とかけ算の計算コストが同じなのは一般的なのですね・・・
でも、不思議です。
かけ算の方が処理が多くなりそうな気がするのですが。
どなたか、ざっくりとで構いませんので
その辺りの原理についても教えていただけないでしょうか?

引用返信 編集キー/
■93410 / inTopicNo.5)  Re[1]: 四則演算の計算コストの比較
□投稿者/ 774RR (757回)-(2019/12/10(Tue) 17:15:08)
こういう測定って実は結構面倒で、例えば
最適化せずに測定しても実際の能力を反映しないとか(演算命令以外の時間を結果に含む)
最適化すると ResultDbl を使っていないからコンパイラは演算をループごと除去してよいとか
他のプログラムの稼働状態に影響を受けるとか
様々な問題をうまく回避しないと正しい結果にならないっす。

で、こういうのは CPU ハードウエアマニュアルを参照すると良くて

例:ワンチップマイコン RX の命令サイクル表から整数演算命令の実行クロック数は
ADD SUB MUL は 1 クロック (符号は無関係)
DIV (符号あり整数除算) は 3-20 クロック
DIVU (符号なし整数除算) は 2-18 クロック

浮動小数点数演算の実行クロック数は (符号なし浮動小数点数ってのはない)
FADD FSUB は 4 クロック
FMUL は 3 クロック
FDIV は 18 クロック

となっていて浮動小数点数演算では乗算のほうが加算より高速だったりします。

x86 や x64 は複雑すぎてマニュアル見てもクロック数の計算は無理


---

組み込み用の小規模で安価な CPU には今でも浮動小数点数演算回路は内蔵されていないので、その場合
整数演算より浮動小数点数演算のほうが時間がかかります。

PC 用の高価な CPU には整数演算回路と浮動小数点数演算回路の両方があり、
コスト度外視して複雑な回路が組んである関係で除算以外はほぼ同じ速度になります。
加算に必要なゲート数と乗算に必要なゲート数では後者のほうが多い。
除算は、専用回路があっても時間がかかるのはしょうがないっす。

引用返信 編集キー/
■93413 / inTopicNo.6)  Re[3]: 四則演算の計算コストの比較
□投稿者/ ねと (3回)-(2019/12/10(Tue) 17:55:45)
2019/12/10(Tue) 17:56:29 編集(投稿者)
ありがとうございます。

ちなみに、
整数も比較してみたのですが、




        Dim ValInt2 As Integer = 1

        Dim ResultInt As Integer


        Dim sw2 As New Stopwatch
        sw2.Restart()

        '空1473 msec
        For i = 1 To 1000000000

            ' 2580 msec
            'ResultInt = i + ValInt2


            ' 2751 msec
            ResultInt = i * ValInt2


            ' 5562 msec
            ResultInt *= CInt(i / ValInt2)

        Next


        Dim hhh = sw2.ElapsedMilliseconds


およそ、Doubleと同程度の計算時間になりましたが、
なぜかDoubleとは違い、わずかだけ足し算よりもかけ算の方が低速な結果が得られました。
これはなぜでしょうか?



組み込み用の小規模で安価な CPUというのは
全てのCore i7 やi9が該当するのでしょうか?
いまCore i7 extremeを使っていますが(20万円しました)
これも安価なCPUに入るのでしょうか?

kakaku.comなどで調べても
20万円よりも高いCPUはほぼ皆無ですが、
高価なCPUとはどれのことを指していますか?

引用返信 編集キー/
■93414 / inTopicNo.7)  Re[4]: 四則演算の計算コストの比較
□投稿者/ ねと (4回)-(2019/12/10(Tue) 18:01:35)
https://paiza.io/projects/wdzsbE94gj1T2nbJcWyfXQ

JAVAでやっても
Integerだとなぜか足し算と引き算だけ
異様に計算時間が短くなります

add:6
sub:6
mul:92
div:743


VB.NETとここまで違うのはなぜでしょうか・・・?

引用返信 編集キー/
■93415 / inTopicNo.8)  Re[4]: 四則演算の計算コストの比較
□投稿者/ 774RR (758回)-(2019/12/10(Tue) 19:33:04)
これが業界間ギャップか

組み込み業界、家電や産業機器の世界では、まあこれはオイラの個人的意見なんだけど
安い = 300円未満
高い = 500円以上
スマホ業界とかだとまた別の基準があるんぢゃないの? そっち系は一切知らんけど。

intel 8086 の時代じゃないし今どきの x86 / x64 CPU には皆、ハードウエアによる加減乗除命令が入っているっす。
なのでオイラの業界から見て PC 用の CPU は Celeron も i9 も Ryzen も皆「超高価」で大差ないっす。

> ResultInt *= CInt(i / ValInt2)
これは除算+乗算(+整数化)だから処理内容が違いすぎて他と同列に比較してはいけない。

> JAVAでやってもIntegerだとなぜか足し算と引き算だけ異様に計算時間が短くなります
これはたしか Java の仮想マシンの仕様で乗算はオーバーフローチェックをする義務があるから。
除算が遅いのはしょうがないっす。

ねぃてぃぶ機械語が直接生成されない .NET や Java をもって 「 CPU の」比較をしちゃだめだよ。

引用返信 編集キー/
■93416 / inTopicNo.9)  Re[5]: 四則演算の計算コストの比較
□投稿者/ ねと (5回)-(2019/12/10(Tue) 19:40:59)
ありがとうございます。

' 2580 msec
'ResultInt = i + ValInt2


' 2751 msec
ResultInt = i * ValInt2

この二つに違いが見られる理由を教えていただけますでしょうか?

引用返信 編集キー/
■93417 / inTopicNo.10)  Re[6]: 四則演算の計算コストの比較
□投稿者/ 774RR (759回)-(2019/12/10(Tue) 19:56:41)
C# と VB で違う checked/unchecked コンテキストの関係かもしれないけど、
その数値の違いが誤差の範囲でない=統計学上有意差があるという保証がないと考慮するだけ無駄っぽいっすよ?

引用返信 編集キー/
■93418 / inTopicNo.11)  Re[7]: 四則演算の計算コストの比較
□投稿者/ ねと (7回)-(2019/12/10(Tue) 20:01:03)
何度が連続して実行してみましたが、
なんどやっても、かけ算の方がわずかだけ
遅くなります

引用返信 編集キー/
■93419 / inTopicNo.12)  Re[8]: 四則演算の計算コストの比較
□投稿者/ 774RR (760回)-(2019/12/10(Tue) 20:49:24)
これらコードが取得しているのはトータルで処理にかかった時間であるため、四則演算命令以外の時間を含みます。
中の処理が四則演算以外はすべて同じという保証がないと、「四則演算命令」のどっちが遅い速いの比較にならないっす。

んで C や C++ などねぃてぃぶ機械語が生成されるのであればそういう検証ができるけど
Java や .NET はいわゆる中間言語を生成していて JIT が再コンパイルしている関係で
JIT の結果を見てみないと断言できないです(そしてそれはかなり困難)

x86 / x64 でも ADD (LEA) 命令と MUL (IMUL) はどちらも同じクロック数だったはずなので、
それ以外のところでなんらかの差があるのでしょう。
ADD (LEA) はどのレジスタでも演算できるのに対して
MUL (IMUL) はレジスタが固定なので、
その辺で生成できる機械語に差が生じて速度差が出るのは当然かと。

後、提示 Java サンプルの除算は被除数がほぼ常に 0 なので、これは比較対象にしてはいけないです。

引用返信 編集キー/
■93422 / inTopicNo.13)  Re[9]: 四則演算の計算コストの比較
□投稿者/ ねと (9回)-(2019/12/11(Wed) 11:21:02)
ありがとうございます。

ちなみに、
CPU ハードウェアマニュアル

というのは売られているものなのでしょうか?
検索しても、それらしい製品が見当たらないのですが・・・

引用返信 編集キー/
■93423 / inTopicNo.14)  Re[10]: 四則演算の計算コストの比較
□投稿者/ 774RR (761回)-(2019/12/11(Wed) 11:48:51)
いやそりゃ CPU なんて星の数ほどもあるわけだしそういう目で探さないと。

intel x64 / x86 CPU ソフトウエア開発マニュアルだったら
https://software.intel.com/en-us/download/intel-64-and-ia-32-architectures-sdm-combined-volumes-1-2a-2b-2c-2d-3a-3b-3c-3d-and-4
でもクロック数は書いてないのであえて読む必要はなさそう

ちょっと、いや、かなり古いけどクロック数について記載がある資料は見つけた (Pentium4)
https://www.intel.co.jp/content/dam/www/public/ijkk/jp/ja/documents/developer/ia32.pdf
core 世代の CPU には適用できない。当然 Ryzen とかにも適用できない。

このクロック数の表は全命令フェッチ全データアクセスが L1 ヒットしたときの話なので
実機の体感実行速度はこの表だけ見てもわからないし、簡単には計算不能。

引用返信 編集キー/
■93441 / inTopicNo.15)  Re[11]: 四則演算の計算コストの比較
□投稿者/ 中 (2回)-(2019/12/12(Thu) 12:10:23)
ひさびさのAMDなんでやってみようかなー
引用返信 編集キー/
■93453 / inTopicNo.16)  Re[12]: 四則演算の計算コストの比較
□投稿者/ 中 (5回)-(2019/12/12(Thu) 13:13:23)
No93441 (中 さん) に返信
> ひさびさのAMDなんでやってみようかなー
VB .NET Core
2605
2592
2590
4943

Pwsh .core
2092
2077
2107
2108
遅すぎてループ回数減らして(1000000)ます。
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ