Pergunta

Eu só queria saber se existe uma maneira elegante de definir a carga máxima da CPU para um thread específico fazendo cálculos intensivos.

No momento, localizei o loop mais demorado do thread (ele faz apenas compactação) e uso GetTickCount() e Sleep() com valores codificados.Ele garante que o loop continue por um determinado período de tempo e que durma por um determinado tempo mínimo.Mais ou menos faz o trabalho, ou seja,garante que o thread não usará mais de 50% da CPU.
No entanto, o comportamento depende do número de núcleos da CPU (grande desvantagem) e é simplesmente feio (menor desvantagem :)).
Alguma ideia?

Foi útil?

Solução

Não tenho conhecimento de nenhuma API para fazer com que o agendador do sistema operacional faça o que você deseja (mesmo que seu thread tenha prioridade ociosa, se não houver threads prontos de maior prioridade, o seu será executado).No entanto, acho que você pode improvisar uma função de aceleração bastante elegante com base no que já está fazendo.Essencialmente (não tenho uma máquina de desenvolvimento do Windows à mão):

Escolha um período padrão de tempo em que o thread ficará suspenso em cada iteração.Então, em cada iteração (ou em cada enésima iteração, de modo que a função de limitação não se torne uma carga significativa da CPU),

  1. Calcule a quantidade de tempo de CPU que seu thread usou desde a última vez que sua função de otimização foi chamada (chamarei isso de dCPU).Você pode usar o GetThreadTimes() API para obter a quantidade de tempo que seu thread está em execução.
  2. Calcule a quantidade de tempo real decorrido desde a última vez que sua função de otimização foi chamada (chamarei isso de dClock).
  3. dCPU / dClock é a porcentagem de uso da CPU (de uma CPU).Se for maior do que você deseja, aumente o tempo de sono; se for menor, diminua o tempo de sono.
  4. Faça seu thread dormir pelo tempo computado.

Dependendo de como o seu watchdog calcula o uso da CPU, você pode querer usar GetProcessAffinityMask() para descobrir quantas CPUs o sistema possui.dCPU / (dClock * CPUs) é a porcentagem do tempo total de CPU disponível.

Você ainda terá que escolher alguns números mágicos para o tempo de suspensão inicial e a quantidade de incremento/decremento, mas acho que esse algoritmo pode ser ajustado para manter um thread em execução bem próximo de uma determinada porcentagem de CPU.

Outras dicas

No Linux, você pode alterar a prioridade de agendamento de um thread com nice().

Não consigo pensar em nenhuma plataforma cruzada do que você deseja (ou em qualquer maneira garantida, ponto final), mas como você está usando GetTickCount, talvez não esteja interessado em plataforma cruzada :)

Eu usaria comunicações entre processos e definiria bons níveis de processos intensivos para obter o que você precisa, mas não tenho certeza se isso é apropriado para sua situação.

EDITAR:Eu concordo com Bernardo é por isso que acho que um processo em vez de um thread pode ser mais apropriado, mas pode não servir aos seus propósitos.

O problema é que não é normal querer deixar a CPU ociosa enquanto você tem trabalho a fazer.Normalmente você define uma tarefa em segundo plano com prioridade IDLE e deixa o sistema operacional cuidar do agendamento de todo o tempo de CPU que não é usado por tarefas interativas.

Parece-me que o problema é o processo de vigilância.

Se a sua tarefa em segundo plano estiver vinculada à CPU, você deseja que ela use todo o tempo não utilizado da CPU para sua tarefa.

Talvez você devesse tentar consertar o programa watchdog?

Você pode alterar a prioridade de um thread, mas alterar a utilização máxima exigiria pesquisas e hacks para limitar quantas coisas estão ocorrendo ou o uso de ferramentas do sistema operacional que podem definir a utilização máxima de um processo.No entanto, não vejo nenhuma circunstância em que você queira fazer isso.

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