Pergunta

Eu tenho a seguinte situação:

Crie uma instância do Boost :: Thread_group e, em seguida, crio threads para processamento paralelo em alguns dados e junto-me aos threads.

Inicialmente, criei os threads para todos os x elementos de dados, assim:

// begin = someVector.begin();
// end = someVector.end();
// batchDispatcher = boost::function<void(It, It)>(...);

boost::thread_group     processors;

// create dispatching thread every ASYNCH_PROCESSING_THRESHOLD notifications
while(end - begin > ASYNCH_PROCESSING_THRESHOLD)
{
    NotifItr split = begin + ASYNCH_PROCESSING_THRESHOLD;

    processors.create_thread(boost::bind(batchDispatcher, begin, split));
    begin = split;
}

// create dispatching thread for the remainder
if(begin < end)
{
    processors.create_thread(boost::bind(batchDispatcher, begin, end));
}

// wait for parallel processing to finish
processors.join_all();

Mas tenho um problema com isso: quando tenho muitos dados, esse código está gerando muitos threads (> 40 threads), o que mantém o processador ocupado com contextos de troca de linhas.

Minha pergunta é a seguinte: é possível chamar Create_thread no Thread_group depois a chamada para join_all.

Ou seja, posso mudar meu código para isso?

boost::thread_group     processors;
size_t                  processorThreads = 0; // NEW CODE

// create dispatching thread every ASYNCH_PROCESSING_THRESHOLD notifications
while(end - begin > ASYNCH_PROCESSING_THRESHOLD)
{
    NotifItr split = begin + ASYNCH_PROCESSING_THRESHOLD;

    processors.create_thread(boost::bind(batchDispatcher, begin, split));
    begin = split;

    if(++processorThreads >= MAX_ASYNCH_PROCESSORS) // NEW CODE
    {                               // NEW CODE
        processors.join_all();      // NEW CODE
        processorThreads = 0;       // NEW CODE
    }                               // NEW CODE
}

// ... 

Quem tem experiência com isso, obrigado por qualquer insight.

Foi útil?

Solução

Eu acredito que isso não é possível. A solução que você deseja pode ser realmente para implementar um Produtor-Consumidor ou um mestre-trabalhador (encadeamento principal 'mestre' divide o trabalho em várias tarefas de tamanho fixo, cria pool de threads 'trabalhadores' e envia uma tarefa para cada trabalhador até que todas as tarefas sejam realizadas).

Essas soluções exigirão alguma sincronização por meio de semáforos, mas eles equalizarão bem o desempenho que você pode criar um thread para cada núcleo disponível na máquina, evitando o desperdício de tempo nos interruptores de contexto.

Outra opção não tão boa e de grande porra é ingressar em um tópico de cada vez. Você pode ter um vetor com 4 threads ativos, ingressar um e criar outro. O problema dessa abordagem é que você pode desperdiçar o tempo de processamento se suas tarefas forem heterogêneas.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top