MQLによる非同期・マルチスレッドプログラミング - ページ 36

 
Vict:

例えば、システムに大きな負荷がかかっていると判断した場合、asyncフラグを付けてジョブを再送信し、遅延させます。

一般的に、私はasync()の遅さにやや失望しています、私は独自の軽量スレッドプールを作成します、それははるかに速くなるように思われます。

デフォルトのasync|deferredモードは、物理リソースが十分でない場合、タスクは新しいスレッドを作成せず、メインスレッドでブロックしながら実行するように本で説明されています。
また、デフォルトモードではメインスレッドがロックされる可能性があることを常に意識しておく必要があります。なぜなら、ほとんどの場合、メインスレッドをブロックしないソリューションが必要だからです。
つまり、物理資源であるCPUの負荷に応じて、タスクを実行する場所を自動的に切り替えるのがデフォルトモードである。
このため、物理リソースが過負荷にならないことが確実な場合は、明示的に std::launch::async のフラグを指定した方がよいでしょう。
しかし、現代のプロセッサの物理リソースをオーバーフローさせると、その能力を最大限に発揮するためには、そのような計算を探す必要があります )) 。
速度については、まだ理論を勉強中なので何とも言えませんが ))

 
Roman:

そのため、物理リソースがオーバーフローしないことが確実な場合は、明示的に std::launch::async というフラグを指定した方がよいでしょう。
そして、現代のプロセッサの物理リソースをオーバーフローさせるには、すべての可能性を選択するために、そのような計算を見つけるのに長い時間がかかります)

プロセッサはさらに多くのスレッドに耐えることができますが、OSの能力がボトルネックになる可能性が高くなります。まあ、スレッドを無限に増やすことはできないので、遅かれ早かれ async(lauch::async, ...) で例外がスローされることになるでしょう。

 
Vict:

プロセッサは大量のスレッドにも耐えられますが、OSの能力がボトルネックになりやすいのです。まあ、スレッドを無限に増やすことはできないので、遅かれ早かれ async(lauch::async, ...) で例外がスローされることになるでしょう。

確かに物理的な限界は常にありますが、mt5のタスクでこの限界を超えることはまずありません。
また、asyncとfutureの戻り値は、ラムダ関数、ref()、.get()などでこの値を取得する方法に関係なく、例外が発生した場合に返されます。
また、std::threadの戻り値では、例外を返すことはできません。

 
Roman:

確かに物理的な限界はありますが、私たちのmt5のタスクでは、この限界を超えることはまずないでしょう。
また、asyncとfutureの戻り値は、ラムダ関数、ref()、.get()などでこの値をどのように取得しても、例外が発生した場合に返されます。
また、std::threadの戻り値では、例外を返すことはできません。

非同期であまり興奮しない方がいいと思います。利便性を重視して作られたようですが、これだけのものが本当に性能を発揮しているようです。プラスワンによるものではありません。

また、戻り値のstd::threadは例外を返すことができません。

必ず必要というわけではありません。しかし、もしそうすれば、(山積みにされたすべての割り当てがなければ、より速く動作するにもかかわらず)12行が追加されることになるのです。
 
Vict:
しかし、もしそうしなければならないなら、それは十数行の追加です(一方で、より速く動作するでしょう-山積みのすべての割り当てがなければ)。

だから、根拠がないように。

#include <thread>
#include <future>
#include <iostream>
#include <chrono>
using namespace std;

template <typename T>
void thread_fn(T &&task) {task(0);}

int main()
{
   packaged_task<int(int)> task{ [](int i){this_thread::sleep_for(3 s); return i==0?throw 0: i;} };
   auto f = task.get_future();
   thread t{thread_fn<decltype(task)>, move(task)};
   t.detach();

   try {
      cout << f.get() << endl;
   }catch(...) {
      cout << "exception caught" << endl;
   }

   return 0;
}

1ダースも必要なかった。しかし、例外を投げることは超非同期的なことではなく、スレッドは全く何も持っていないということです。

 
おそらく、実用的な観点からは、これらのクッションから離れ、WindowsのAPI(CreateThread、同期プリミティブ、インターロック関数)を思い出すことに価値があるのでしょう。全部、あるんです。もちろん、風のために書くときは。MT4やMT5には、遅延計算やプールなどの複雑なタスクはないのに、なぜ複雑にするのでしょうか。
 
Andrei Novichkov:
MT4|MT5には遅延計算やプールなどを必要とする複雑なタスクはないのに、なぜ複雑化するのでしょうか?
実は、タスクがあるんです。MTには能力がない。
ここでは、あらゆる種類のプールは本当に不要です。標準的なマルチスレッドソリューションは、正しく適用されれば十分です。
 
Yuriy Asaulenko:
実は、課題はそこにあるのです。MTの可能性はゼロではありません。
ここでは、あらゆる種類のプールは本当に不要です。標準的なマルチスレッドソリューションは、正しく適用されれば十分です。
そういうことなんです。
 

みんな、僕の研究を教えてあげるよ。

土下座して自分のスレッドプールを書きました。このバージョンは非常に機能的で、どんなファンクタでも、どんなパラメータでも渡すことができ、その応答として未来が返される、つまり、例外のキャッチと終了待ちの形ですべてのプラッシュカが利用可能です。そして、https://www.mql5.com/ru/forum/318593/page34#comment_12700601 と同じくらい良いものです。

#include <future>
#include <iostream>
#include <vector>
#include <mutex>
#include <set>

mutex mtx;
set<thread::id> id;
atomic<unsigned> atm{0};

int main()
{
   Thread_pool p{10};
   for (int i = 0;  i < 10000;  ++ i) {
      vector<future<void>> futures;
      for (int i = 0; i < 10; ++i) {
         auto fut = p.push([]{
                              ++ atm;
                              lock_guard<mutex> lck{mtx};
                              id.insert( this_thread::get_id() );
                           });
         futures.push_back(move(fut));
      }
   }
   cout << "executed " << atm << " tasks, by " << id.size() << " threads\n";
}

std::asyncは誰がどのような状態で書いたのか知りませんが、私の膝で開発したものは標準のものより4倍速いです(10スレッド動作)。コア数よりスレッド数を増やしても遅くなるだけだ。プールサイズ==コア数(2)の場合、非同期は約30倍負ける。そういうことなんですね。

スレッドをプールする場合は、確実に標準的な非同期ではありません )) 。

 
Vict:

みんな、僕の研究を教えてあげるよ。

土下座して自分のスレッドプールを書きました。このバージョンは非常に機能的で、どんなファンクタもどんなパラメータでも渡すことができ、その応答として未来が返される。つまり、例外のキャッチや終了待ちの形で、すべてのプラッシュカが利用できる。そして、そこと同じように使いましたhttps://www.mql5.com/ru/forum/318593/page34#comment_12700601

std::asyncは誰がどのような状態で書いたのか知りませんが、私の膝で開発したものは標準のものより4倍速いです(10スレッド動作)。コア数よりスレッド数を増やしても遅くなるだけだ。プールサイズ==コア数(2)の場合、非同期は約30倍負ける。そういうことなんですね。

スレッドをプールする場合は、確実に標準的な非同期ではありません )) 。

調査ありがとうございました。良い例であり、考えるべきことであり、学ぶべきことです。
しかし、今回の総論では、ほとんどの人が「流水プールはあまり必要ない」という結論に至っています。
私の場合、確かに、プールがスレッド数で固定されていることに気づいたので、それはうまくいきませんね。
でも、そうですね、プールが必要なときは、あなたの例がちょうどいいでしょうね。例を示していただき、ありがとうございます。
まだコツを掴んでいないのですが ))