Programação assíncrona e multi-tarefa em MQL - página 34

 
Andrei Novichkov:
Mas será que existem tarefas que realmente requerem o agrupamento de fios? Não apenas - criar um fio, esquecê-lo e esperar que se esgote, mas exatamente uma piscina, como Williams o descreve? Parece ser um exemplo de caixa eletrônico, se não estou enganado - que tarefa poderia justificar um judô tão milagroso? Ainda não consigo pensar em tal tarefa. E por que você não olha realmente para o ThreadPool onde tudo já está feito, há documentação e exemplos.

Para ser honesto, até agora eu não vi muito sentido entrestd::async e thread pool, exceto questd::async cria e elimina automaticamente um thread para a tarefa em questão.
E para utilizar o pooling de fios, é necessário saber antecipadamente o número de fios utilizados no programa, e definir este número para o pool explicitamente.
Acontece que o agrupamento de fios é estático em termos de número de fios, embora isso possa não ser o caso, não posso afirmar.
Mas no livro de Williams, ele diz que o agrupamento de fios é recomendado quando há muitas tarefas a serem executadas em std::thread.
E talvez isto não se aplique àstd::async, eu ainda não entendi completamente o significado.
E a assincronia é muito requisitada em soluções de rede e estratégias de múltiplos símbolos, e para cálculos carregados também é útil.
Mas tendostd::async e std::promessa no padrão, eu acho que não há necessidade de criar um pool de fios.

 

Há também uma pergunta sobre a criação de um projeto para dll.
Como se livrar das funções não utilizadas, que são automaticamente puxadas para a dependência dll pelos compiladores?

Já tentei ambientes de desenvolvimento diferentes, e cada um deles puxa sua própria função não utilizada.
MSVS_2017 até mesmo puxa suas próprias dependências de tempo de execução, das quais eu acho que não posso me livrar.
Portanto, eu tentei diferentes IDEs, mas elas também puxam funções não utilizadas.
Como se livrar deles?

Arquivos anexados:
 
Roman:

Para ser honesto, não tenho capturado muito sentido entrestd::async e thread pooling, exceto que std::async cria e apaga automaticamente um fio para a tarefa em questão.
E para utilizar o pooling de fios, é necessário saber antecipadamente o número de fios utilizados no programa, e definir este número para o pool explicitamente.
Acontece que o agrupamento de fios é estático em termos de número de fios, embora isso possa não ser o caso, não posso afirmar.
Mas, no livro de Williams, ele diz que o agrupamento de fios é recomendado quando há muitas tarefas a serem executadas em std::thread.
E talvez isto não se aplique àstd::async, eu ainda não entendi completamente o significado.
E a assincronia é muito requisitada em soluções de rede e estratégias de múltiplos símbolos, e para cálculos carregados também é útil.
Mas tendostd::async e std::promessa no padrão, eu acho que não há necessidade de criar um pool de fios.

Assim, o ponto principal da assimetria é usar o pool de fios, livrar-se da criação/eliminação de fios, se assimetria não fizer isso, então é inútil.

Bem, na verdade, eu estava pensando muito mal sobre a assimetria, aparentemente. Um simples teste mostra-o como uma coisa bastante adequada:

#include <future>
#include <iostream>
#include <vector>
using namespace std;

int main()
{
    cout << "Main thread id: " << this_thread::get_id() << endl;
    for (int i = 0;  i < 2;  ++ i){
       cout << "------------------------" << endl;
       vector<future<void>> futures;
       for (int i = 0; i < 10; ++i)
       {
          this_thread::sleep_for(1 ms);
          auto fut = async([]{
                              this_thread::sleep_for(1 s);
                              cout << this_thread::get_id() << '\n';
                           });
          futures.push_back(move(fut));
       }
       for (auto &f : futures)
          f.wait();
    }

    cout << endl;
}

Main thread id: 140657228855104

140657228850944
140657220458240
140657212065536
140657203672832
140657195280128
140657186887424
140657178494720
140657170102016
140657161709312
140657153316608
------------------------
140657153316608
140657161709312
140657170102016
140657178494720
140657228850944
140657220458240
140657212065536
140657203672832
140657195280128
140657186887424

Você pode ver que para o segundo lote de trabalhos assimétricos foram utilizados fios previamente criados e não foram criados novos. Então eu não estava exatamente diluindo merecidamente, eu acho.

 
Roman:

Há também uma pergunta sobre a criação de um projeto para dll.
Como posso me livrar de funções não utilizadas que são automaticamente puxadas para a dependência dll pelos compiladores?

Para mingw a opção -static deve ajudar com a estática ela deixa de gerar pic

 

Teste de assimetria mais difícil

#include <future>
#include <iostream>
#include <vector>
#include <mutex>
#include <set>
using namespace std;

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

int main()
{
   for (int i = 0;  i < 10000;  ++ i) {
      vector<future<void>> futures;
      for (int i = 0; i < 10; ++i) {
         auto fut = async(launch::async,[]{
                                           ++ 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";
}
// cout: executed 100000 tasks, by 10 threads

Bem, sim, funciona bem. Por que eu pensei tão mal disso? Provavelmente uma implementação torta no alvorecer de c++11 ...

SZY: mas devo notar que a assimetria anormalmente lenta() com lanch::async policy, se você substituir por lanch::deferred (+ esperar pela conclusão do trabalho no final do primeiro ciclo), então este simples teste começa a trabalhar 30 vezes mais rápido!!! Lá se vai a multithreading )). Assim, isso deixa espaço para uma piscina de linha caseira, parece-me que ela pode ser feita muito mais rapidamente do que a normal.

 
Roman:

Há também uma pergunta sobre a criação de um projeto para dll.
Como se livrar das funções não utilizadas, que são automaticamente puxadas para a dependência dll pelos compiladores?

Já experimentei diferentes IDEs, e cada uma delas puxa sua própria função não utilizada.
MSVS_2017 até mesmo puxa suas próprias dependências de tempo, das quais eu acho que não posso me livrar.

Tome-o como certo e esqueça-o, ou esqueça-o.
O que e por que é um incômodo? Deixe o absurdo para os vizinhos).
Idiomas de alto nível são criados para que um programador não se preocupe com detalhes. Não é um assunto do czar. Sim, e como saber o que você precisa e o que você não precisa. O compilador é quem melhor sabe.
 
Vict:

Teste de assimetria mais difícil

Bem, sim, funciona bem. Por que eu pensei tão mal disso? Provavelmente uma implementação torta no alvorecer de c++11 ...

SZY: mas devo notar que a assimetria anormalmente lenta() com lanch::async policy, se você substituir por lanch::deferred (+ esperar pela conclusão do trabalho no final do primeiro ciclo), então este simples teste começa a trabalhar 30 vezes mais rápido!!! Lá se vai a multithreading )). Assim, isso deixa espaço para uma piscina de linha caseira, parece-me que ela pode ser feita muito mais rapidamente do que a normal.

Eu não li até o final e decidi sugerir que você corresse com a bandeira adiada ))))) Faz sentido, se tal teste funciona mais rápido, geralmente penso que esta forma de utilizá-lo é preferível, por que colocar limites rígidos. Só queria dizer obrigado por sua ligação com Git, assisti com interesse )) Eu gostei que houvesse duas versões - com e sem impulso.

Romano:

Outra pergunta surgiu sobre a criação do projeto para a dll.
Como posso me livrar das funções não utilizadas, que são automaticamente puxadas para a dependência dll pelos compiladores?

Eu já tentei ambientes de desenvolvimento diferentes, e cada um deles puxa sua própria função não utilizada.
MSVS_2017 até mesmo puxa suas próprias dependências de tempo, das quais eu acho que não posso me livrar.
Portanto, eu tentei diferentes IDEs, mas elas também puxam funções não utilizadas.
Como se livrar deles?

Como você pode fazer sem alardear? E sim, é diferente em todos os lugares. Não, sem empurrar ou puxar )))) Você ainda não trabalhou com QT, é aí que toda uma guirlanda de salsichas DLL é puxada.


 
Andrei Novichkov:

Eu não li até o final e decidi sugerir que você corresse com a bandeira adiada ))))



Por que precisamos de async() com a bandeira diferida? Eu realmente não entendo, você pode explicar?

 
Vict:

Por que precisamos de async() com a bandeira diferida? Eu realmente não entendo, você pode explicar?

Na verdade, por que você não lê sobre a bandeira na documentação? Em https://en.cppreference.com . E exemplos com discussão no stackoverflow.com. Normalmente uso estas fontes de informação e aconselho que façam o mesmo.

 
Andrei Novichkov:

Por que não ler de fato sobre a bandeira na documentação? Em https://en.cppreference.com . E exemplos com discussão no stackoverflow.com. Normalmente uso estas fontes de informação e aconselho que façam o mesmo.

MSDN. Documentação completa. O resto é apenas material suplementar.