標準的な機能/アプローチの代替実装 - ページ 11

 
Nikolai Semko:
リンクを送っていただけませんか?

持っていなかった。こちらの フォーラムで言及されています。自分で検索エンジンに目を通した。

Вопрос к сообществу программистов по поводу авторства
Вопрос к сообществу программистов по поводу авторства
  • 2017.11.24
  • www.mql5.com
Общее обсуждение: Вопрос к сообществу программистов по поводу авторства
 
fxsaber:

持っていなかった。こちらの フォーラムで言及されています。自分で検索エンジンを使って検索した。

見てきました。画素のカラーミキシングがないと、とても原始的なんです。
ただ、私が掲示板で出会ったものは、すべて幼稚園児レベルだったんです。そして、もう5年生になるんです。
 
Nikolai Semko:
ただ、私が掲示板で出会ったものは、すべて幼稚園児レベルだったんです。そして、もう5年生になるんです。

明らかに、これらのバイクはすべて何度も何度もリビルドされています。asmの実装に至るまで、本まで出版された。

今では、ほとんどの人があらゆる場面で関連するAPIを利用しているため、基本的なことはわかりにくくなっています。

だから、掲示板に登録して聞いてみるしかないんです。

 
fxsaber:

明らかに、これらのバイクはすべて何度も何度もリビルドされています。書籍でも、asmの実装までが出版されています。

今では、ほとんどの人があらゆる場面で関連するAPIを利用しているため、基本的なことはなかなかわかりません。

だから、フォーラムに登録して聞くしかないんです。

それが、難しいんです。とにかく、見つからなかったんです。もしかしたら、私の見方が悪かったのかもしれません。フォーラムでは、誰もが標準的なクローズド・ライブラリーを送り、「何でも使えるのに、なぜそれが必要なのか」と不思議に思うでしょう。もちろん、JavaやJavaScriptなどで書いていれば頭を悩ますことはない。とか、市場が必要とされていないとか。
よし、もうこの件に関しては、今のところ堂々と一人でやることに慣れた。続けて、さらに、この方向でほぼすべての実装を理解する上で、実質的に空白の時間がないのです。そしてその一方で、ユニークな技術も身につけました。
 
pavlick_:

LONG_MAX/MINを 使用しないのはなぜですか?なんとなく見た目もすっきりしますしね。いい感じだと思いますよ。gccでテストしてみました(もちろん、コンパイラは手元にあった非常に古い5.4.0を最小限の修正で)。


まあ、そうですね、いい加減なものです。しかし、LONG_MAX= 9223372036854775807 は 9007199254740992 よりも多い。また、この数値の16進数である0x20000000000000は、ulong型にしか使えないため、忌み嫌われています。どうしたら分かりやすくなるのかも分からない。(ulong)(1<<53)と書くと時間がかかるので書けません。

double 型は,LONG_MAX 値からではなく,可能な最大仮数から小数部を除いた整数を含むようになる.しかし、仮数には53ビットが許され、すなわち2^53=9007199254740992となります。

pavlick_:

出力はナノ秒ではなくミリ秒ですし、なぜマイナスt0が必要なのかがまだわかりません。

t0 は、素数倍和の 1000000 パスのフルサイクルの時間です。

tは同じ2値の和の同じ周期の時間であるが、関数ceil, ceil, roundなどを通過したものである。

その差分(t-t0)が、これらの機能に費やした正味の時間であるというロジックで進めました。

もちろん、より客観性を高めるには、何度も測定することが必要です。

- ナノでは、100万回のうち1回分の機能を果たすのにかかる時間を基準に計算しています。まさにin nanoが正解です。

pavlick_:

gcc上であなたのテストを実行しました(もちろん、手元にあったコンパイラは非常に古い5.4.0ですが、最小限の修正を加えています)。

1.O3付きでコンパイルしています。

2.オファストとのコンパイル

それでわかったことがある。コンパイルされたMQL5のコードは、Ofastよりも高速に動作するのですか?信じられませんね。 そこには32ビットコンパイラがあったはずです。
 
Nikolai Semko:

(ulong)(1<<53)と書いてはいけない、それはもう時間のかかる操作だからだ。

この操作は、文字列を含む定数に対するすべての操作と同様、時間を要しない。

input long l = (ulong)1 << 53;
input string s = (string)__DATETIME__ + __FILE__;
 
fxsaber:

この操作は、文字列を含むすべての定数と同様に時間を要しない。

わー、かっこいいー。ありがとうございます。そして、毎回カウントしているのでは?ええ、まあ、論理的には、もうコンパイル時に計算できるんですけどね。
それじゃ、これでおしまい。

double Ceil (double x) { return double((x>(long)1 << 53 || x<-(long)1 << 53 )?x:(x-(long)x>0)?(long)x+1:(long)x);}
double Round(double x) { return double((x>(long)1 << 53 || x<-(long)1 << 53 )?x:(x>0)?(long)(x+0.5):(long)(x-0.5));}
double Floor(double x) { return double((x>(long)1 << 53 || x<-(long)1 << 53 )?x:(x>0)?(long)x:((long)x-x>0)?(long)x-1:(long)x);}
2018.08.26 18:04:07.638 TestRound (EURUSD,M1)   Время цикла без округления = 1.302 наносекунд, сумма = 115583114403605978808320.00000000
2018.08.26 18:04:07.642 TestRound (EURUSD,M1)   Время выполнения функции ceil =  2.389 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 18:04:07.644 TestRound (EURUSD,M1)   Время выполнения функции Ceil =  0.223 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 18:04:07.648 TestRound (EURUSD,M1)   Время выполнения функции floor = 2.884 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 18:04:07.649 TestRound (EURUSD,M1)   Время выполнения функции Floor = 0.122 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 18:04:07.654 TestRound (EURUSD,M1)   Время выполнения функции round = 3.413 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 18:04:07.656 TestRound (EURUSD,M1)   Время выполнения функции Round = 0.222 наносекунд, Контрольная сумма = 1.15583114403606 e+23
2018.08.26 18:04:07.656 TestRound (EURUSD,M1)   Идет бесконечный поиск расхождения по случайным числам double ... Прервите скрипт, когда надоест ждать

ただし、53ではなくDBL_MANT_DIGと 書く方が正しいでしょう

double Ceil (double x) { return double((x>(long)1 << DBL_MANT_DIG || x<-(long)1 << DBL_MANT_DIG )?x:(x-(long)x>0)?(long)x+1:(long)x);}
double Round(double x) { return double((x>(long)1 << DBL_MANT_DIG || x<-(long)1 << DBL_MANT_DIG )?x:(x>0)?(long)(x+0.5):(long)(x-0.5));}
double Floor(double x) { return double((x>(long)1 << DBL_MANT_DIG || x<-(long)1 << DBL_MANT_DIG )?x:(x>0)?(long)x:((long)x-x>0)?(long)x-1:(long)x);}

doubleの値がすべて小数である場合の利得が最小となるケース。

2018.08.26 18:20:35.408 TestRound (EURUSD,M1)   Время выполнения функции sqrt = 1.083 наносекунд, сумма = 81969849.90928555
2018.08.26 18:20:35.413 TestRound (EURUSD,M1)   Время выполнения функции ceil =  3.579 наносекунд, Контрольная сумма = 5250492895.0
2018.08.26 18:20:35.416 TestRound (EURUSD,M1)   Время выполнения функции Ceil =  1.249 наносекунд, Контрольная сумма = 5250492895.0
2018.08.26 18:20:35.422 TestRound (EURUSD,M1)   Время выполнения функции floor = 3.931 наносекунд, Контрольная сумма = 5249492896.0
2018.08.26 18:20:35.424 TestRound (EURUSD,M1)   Время выполнения функции Floor = 0.513 наносекунд, Контрольная сумма = 5249492896.0
2018.08.26 18:20:35.427 TestRound (EURUSD,M1)   Время выполнения функции round = 1.519 наносекунд, Контрольная сумма = 5249992896.0
2018.08.26 18:20:35.429 TestRound (EURUSD,M1)   Время выполнения функции Round = 0.571 наносекунд, Контрольная сумма = 5249992896.0
ファイル:
TestRound.mq5  11 kb
 
Nikolai Semko:
それでわかったことがある。コンパイルされたMQL5のコードは、Ofastでさえも高速に動作すること?32ビットコンパイラを搭載していたはずなのに、信じがたいことです。

私はすべてからマイナスt0を取り出し(何らかのエラーだと思った)、私の出力はシングルパスではなく、ループ全体が計量されています。繰り返しあたりの出力をナノ秒に換算すると(1行目の「丸めなしのサイクルタイム」-数え方は同じです)、次のようになります。

-O3
Время цикла без округления = 1.099 наносекунд, сумма = 1.15583114 e+23
-Ofast
Время цикла без округления = 0.552 наносекунд, сумма = 1.15583114 e+23

gccではあまり加速されません(-Ofastではさらに遅くなります)。mccでは、あなたのテストから判断すると、かなりの速度向上が見られますが。

の場合、1,000,000回中985,651回、つまりほぼすべての反復計算がx < MIN || x > MAXの条件を満たしていることがわかります。


-Ofast は、すべての inf/nan チェック、errno 設定を無効にする、つまり fpu の丸め誤魔化しておく。そして、このむき出しの丸めは、x < MIN || x > MAXという単純な比較では負けることはないのです。

 
pavlick_:

gccではあまり加速さ れません(-Ofastではさらに遅くなります)。μlでは重要です。

しかし、なかなか言い出せない。T0をいい数字で投げ出して、20倍の差がつきました。ループ(+t0)という最小限のコードを追加するだけで、数十倍美しい結果が、2倍程度で見劣りするようになるのです。また、それが単なるループではなく、何か有用なことをしている本物のアルゴリズムだとしたら、何と言えるでしょうか。その差は目に見えるものではなく、小数点のずっと後にぶら下がるもので、ボトルネックになることはほとんどないでしょう。実際のアプリケーションでは、ミューテックス・ピックアップ、CPUバリア、メモリ割り当ての 方が丸めよりもずっとコストがかかります。全体として、賭けに出る価値はないと思います。

 
pavlick_:

その差は目に見えるものではありませんし、小数点のずっと後にあるもので、ボトルネックになることはないでしょう。実際のアプリケーションでは、ミューテックス、CPUバリア、メモリ割り当てなどの コストは丸め込みよりもはるかに高くなります。全体として、賭けに出る価値はないと思います。

これは99%そうです、はい。

最適化する前に、最適化するものが あることを確認する必要があります。

私が実践してきた中で、atofの実装が本当に役に立ったケースは1つしか覚えていません。そう思えたけれど。

そして、どんな最適化(***を除く)も無料ではないことを心に留めておく必要があります。