MQL의 비동기 및 다중 스레드 프로그래밍 - 페이지 36

 
Vict :

내 마음에 떠오르는 유일한 합리적인 설명은 풀에서 실행 중인 스레드 수를 수동으로 제어하는 것입니다(기본 async | deferred를 신뢰하지 않는 경우). 예를 들어, 시스템에 과부하가 걸리면 작업 전송을 중지합니다. async 플래그를 사용하여 deferred를 보냅니다.

글쎄, 일반적으로 나는 async()의 느림에 다소 실망했습니다. 가벼운 스레드 풀을 구성할 시간이 있을 것입니다. 훨씬 더 빠를 것 같습니다.

기본 비동기|지연 모드는 현재 물리적 리소스가 충분하지 않은 경우 작업이 새 스레드를 생성하지 않고 메인 스레드에서 실행되어 차단하는 방식으로 책에 설명되어 있습니다.
그리고 기본 모드에서 메인 스레드가 차단될 수 있다는 점을 항상 기억해야 합니다. 기본적으로는 반대로 메인 스레드를 차단하지 않도록 솔루션이 필요하기 때문입니다.
즉, 기본 모드는 물리적 리소스, 즉 프로세서의 부하에 따라 작업을 실행할 위치를 자동으로 전환합니다.
따라서 물리적 리소스가 오버플로되지 않을 것이라고 확신하는 경우 명시적으로 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는 예외를 반환할 수 없습니다.

IMHO, 비동기에 너무 집착하지 마십시오. 편의상 그렇게 한 것 같지만 이 모든 것이 특히 성능에 영향을 미치는 것 같습니다. 플러스가 아니라..

그리고 반환 값의 std::thread는 예외를 반환할 수 없습니다.

항상 필요한 것은 아닙니다. 그러나 필요한 경우 이것은 12개의 추가 라인입니다(힙에 할당하지 않고 더 빠르게 작동한다는 사실에도 불구하고).
 
Vict :
그러나 필요한 경우 이것은 12개의 추가 라인입니다(힙에 할당하지 않고 더 빠르게 작동한다는 사실에도 불구하고).

근거 없는 일이 없도록:

#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 ;
}

10도 걸리지 않았습니다. 예, packages_task와 미래가 없으면 훨씬 더 낮은 수준이 가능하지만 예외를 던지는 아이디어는 일종의 비동기 슈퍼 기능이 아니며 스레드는 전혀 그렇지 않습니다.

 
아마도 실용적인 관점에서 때때로 이러한 모든 장점에서 벗어나 Windows API(CreateThread, 동기화 기본 요소, 연동 기능)를 기억하는 것이 좋습니다. 그래도 있습니다. 물론 Windows용으로 작성된 경우입니다. 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를 어떤 상태로 작성했는지 모르지만 내 무릎 깊이의 기술은 표준 기술(10개의 실행 스레드 포함)보다 약 4배 빠릅니다. 또한 코어 수보다 스레드 수가 많아지면 속도가 느려질 뿐입니다. 풀 크기 == 코어 수(2)에서 비동기는 약 30배 손실됩니다. 그게 다야

스레드 풀을 원하면 확실히 표준 비동기가 아닙니다.)).

 
Vict :

여러분, 저는 제 연구를 공유하고 있습니다.

내 스레드 풀을 무릎에 썼습니다. 이것은 완전히 기능적인 버전이므로 매개변수와 함께 모든 펑터를 전달할 수 있습니다. 응답으로 미래가 반환됩니다. 예외를 포착하고 완료를 기다리는 형태의 모든 장점을 사용할 수 있습니다. 그리고 나는 그것을 https://www.mql5.com/ru/forum/318593/page34#comment_12700601 처럼 사용했습니다.

누가 std::async를 어떤 상태로 작성했는지 모르지만 내 무릎 깊이의 기술은 표준 기술(10개의 실행 스레드 포함)보다 약 4배 빠릅니다. 또한 코어 수보다 스레드 수가 많아지면 속도가 느려질 뿐입니다. 풀 크기 == 코어 수(2)에서 비동기는 약 30배 손실됩니다. 그게 다야

스레드 풀을 원하면 확실히 표준 비동기가 아닙니다.)).

연구에 감사드립니다. 좋은 예입니다. 공부해야 할 것이 있습니다.
그러나 일반적인 논의에서 우리 대부분은 스레드 풀이 실제로 실제로 필요하지 않다는 결론에 도달했습니다.
제 경우에는 풀이 스레드 수 면에서 정적이라는 것을 깨달았기 때문에 이것은 저에게 적합하지 않습니다.
그리고 예, 풀이 필요할 때 귀하의 예는 풀을 위한 것일 뿐입니다. 예를 보여 주셔서 감사합니다.
나는 여전히 간단한 이해로 이해하기 시작했습니다))