É uma proporção ideal de tempo de usuário para tempo real um indicador para paralelização eficiente?

3

Em alguns shells unix existe o comando time que imprime quanto tempo um determinado comando leva para ser executado. A saída parece

real  1m0.000s
user 10m0.000s
sys   0m0.000s

Se eu escrever um programa que usa paralelização em vários núcleos, o tempo de usuário pode ser um múltiplo do tempo real.

A minha pergunta é, se posso concluir, que se o tempo do usuário é muito próximo do tempo real multiplicado pelo número de threads usados, que o programa é paralelizado de forma otimizada? Ou seja, que, por exemplo, nenhum thread precisa esperar por longos períodos de tempo para outros threads.

    
por HerpDerpington 19.07.2018 / 18:28

1 resposta

3

Em uma palavra simples: Não.

O que desperdiça muito esforço é alternar entre o espaço do kernel e o espaço do usuário, essa comutação é onde o maior desperdício é produzido. Há (muito) trabalho apenas para chegar onde a operação real precisa ser executada. Quanto menos switches precisassem da operação mais eficiente deveria ser.

Existem operações que são feitas completamente no espaço do kernel (e não há maneira (segura) de contornar isso). Nesses casos, a maior parte do tempo é gasto no espaço do kernel, e essa é a maneira mais eficiente de executá-los.

Existem outras operações que devem ser executadas no espaço do usuário, pois o kernel não possui serviço / função que o implemente. Em tais operações, quanto mais tempo for usado no espaço do usuário, mais eficiente será a operação.

Mas alguém pode ter implementado um serviço de kernel eficiente no espaço do usuário com algum algoritmo não tão eficiente. Isso aumentará o tempo do usuário, mas o resultado seria menos eficiente. Comparado com o mesmo serviço no espaço do kernel.

E algum outro desenvolvedor pode estar chamando o kernel para ler um byte de cada vez (e ter que alternar para cada byte) em vez da chamada equivalente para ler um meg de cada vez (se houver uma função equivalente para um bloco em vez de um byte).

E, no final, deve ser que alguma mistura de operações do kernel e do usuário seja executada. Para ler um bloco de disco, por exemplo, o kernel deve fornecer a função e deve ser um "disparar e esquecer" até que o bloco de memória (buffer) seja preenchido com o resultado da leitura do bloco de disco. Para acessar a memória do processo (como uma matriz de programa), nenhuma chamada de kernel deve ser necessária.

Não há uma maneira simples de medir a eficiência do tempo.

    
por 19.07.2018 / 19:37