Por que temos que esperar pela E / S?

28

Sempre se sabe que as operações do disco são lentas e sabemos os motivos pelos quais elas são lentas. Portanto, a pergunta aqui é por que precisamos esperar por E / S ou por que existe algo como IOWait etc.?

Quero dizer, notei que, quando você está executando algumas tarefas de E / S em segundo plano, seu computador fica muito mais lento, eu notei especialmente que ao usar o Linux, se você estiver executando algumas tarefas de E / S mais longas , o sistema operacional se torna quase inutilizável até que sejam concluídos.

Na verdade, eu também encontrei esse tópico em um artigo, há um trecho:

A espera de E / S é de 12,1%. Este servidor possui 8 núcleos (via cat / proc / cpuinfo). Isso é muito próximo a (1/8 núcleos = 0,125)

Então, basicamente, significa que está diminuindo bastante o computador, por que isso? Quero dizer OK, agora o computador normal tem pelo menos 2 núcleos, às vezes 4 ou às vezes eles têm mais por causa do hyperthreading ou algo assim. Mas agora a questão é por que a CPU realmente precisa ficar lá, praticamente não fazendo mais nada além de apenas esperar por E / S? Quero dizer a idéia básica ou a arquitetura do gerenciamento de processos, agora não sei se é o SO responsável por isso ou se trata da parte do hardware, mas deve ser possível que a CPU aguarde ou verifique regularmente, enquanto realmente executa muitas outras tarefas e só volte ao processo de E / S quando estiver pronto. De fato, se essa é uma tarefa tão difícil e a CPU tem que esperar, por que não é ' que gerenciado pelo hardware com mais eficiência? Por exemplo, poderia haver algum tipo de mini CPU que esperaria por ele e entregaria a pequena parte dos dados à CPU real assim que ela retornasse ao processo e, assim, o processo seria repetido e não teríamos praticamente dedicar todo o núcleo da CPU ao processo de cópia de dados ... Ou seria eu quem deveria inventar esse tipo de coisa e receber um prêmio nobel por isso? : S

Agora, tudo bem, eu estou realmente colocando isso agora da perspectiva dos observadores e realmente não fui tão fundo no assunto, mas realmente não entendo por que a CPU precisa trabalhar com a velocidade do disco rígido, enquanto poderia faça outra coisa e volte ao HDD quando estiver pronto. A idéia não é acelerar o aplicativo que precisa dessa operação de E / S, do processo de cópia ou de qualquer outra coisa, mas a idéia é afetar minimamente o consumo da CPU durante a execução dessa operação, para que o sistema operacional possa utilizá-lo para outros processos e para o usuário. não precisaria sentir um atraso geral do computador ao fazer algumas operações de cópia ...

Arturas M
fonte
41
"enquanto isso poderia fazer outra coisa" - como? Ele precisa trabalhar com dados. Se esses dados não estiverem no cache L1 da CPU, é necessário buscá-los no cache L2. Se não estiver no cache L2, ele precisará buscar no L3 (se houver). Se não estiver presente nos caches de dados, ele precisará acessar a memória principal. Se não estiver na memória principal ... precisa acessar o HDD.
Oded
39
O computador faz outra coisa; o kernel bloqueia o thread até que a operação de E / S seja concluída, permitindo a execução de outros threads / processos. Mas se tudo estiver aguardando no disco IO, não há mais nada a fazer.
Coronel Thirty Two
6
Você precisa esperar que os programas cheguem à torre de E / S e enviar seus frisbees!
Almo
11
@immibis Correct! :)
Almo
2
Normalmente, sistemas operacionais modernos fazem o que você está reclamando que não fazem - as operações de E / S são despachadas para o hardware apropriado e as interrupções são geradas pelo hardware para indicar que as operações estão concluídas. Os processos que aguardam IO geralmente são bloqueados enquanto aguardam (isso pode ser alterado). Se muitos processos estiverem aguardando IO e nenhum outro processo tiver algo que a CPU faça, não há muito o que fazer. Você também pode acabar no inferno de troca de mem. Escrever programas para utilizar com eficiência CPU, memória e E / S requer habilidades especiais, e o que mais está sendo executado também afeta o que funciona melhor.
Nategoose 9/09/15

Respostas:

19

Os esquemas de E / S que você está descrevendo estão em uso atual em computadores.

por que a CPU realmente tem que ficar lá, praticamente não fazendo nada além de apenas esperar por E / S?

Este é o método de E / S mais simples possível: E / S programada . Muitos sistemas embarcados e microprocessadores low / end possuem apenas uma única instrução de entrada e uma única instrução de saída. O processador deve executar uma sequência explícita de instruções para cada caractere lido ou gravado.

mas deve ser possível que a CPU aguarde ou verifique regularmente, enquanto realiza muitas outras tarefas e só volta ao processo de IO quando estiver pronta

Muitos computadores pessoais têm outros esquemas de E / S. Em vez de esperar em um loop apertado para que o dispositivo fique pronto ( espera ocupada ), a CPU inicia o dispositivo de E / S pedindo para gerar uma interrupção quando terminar ( E / S acionada por interrupção ).

Embora a E / S acionada por interrupção seja um passo à frente (comparada à E / S programada), exige uma interrupção para cada caractere transmitido e é cara ...

Por exemplo, poderia haver algum tipo de mini CPU que esperaria por ele e entregaria a pequena parte dos dados à CPU real assim que ela retornasse ao processo e, assim, o processo seria repetido e não teríamos dedicar praticamente todo o núcleo da CPU ao processo de cópia de dados ...

A solução para muitos problemas está em ter alguém para fazer o trabalho! :-)

O controlador / chip DMA (Direct Memory Access) permite E / S programada, mas é necessário que outra pessoa faça!

Com o DMA, a CPU precisa inicializar apenas alguns registros e é livre fazer outra coisa até que a transferência seja concluída (e uma interrupção seja gerada).

Mesmo o DMA não é totalmente gratuito: dispositivos de alta velocidade podem usar muitos ciclos de barramento para referências de memória e referências de dispositivo ( roubo de ciclo ) e a CPU precisa esperar (o chip DMA sempre tem uma prioridade de barramento mais alta).

A espera de E / S é de 12,1%. Este servidor possui 8 núcleos (via cat / proc / cpuinfo). Isso é muito próximo a (1/8 núcleos = 0,125)

Penso que isto é de: Noções básicas sobre E / S de disco - quando você deve se preocupar?

Bem, não é estranho: o sistema (mySQL) deve buscar todas as linhas antes de manipular dados e não há outras atividades.

Aqui não há um problema de arquitetura / SO do computador. É assim que o exemplo é definido.

No máximo, pode ser um problema de ajuste do RDBMS ou um problema de consulta SQL (índice ausente, plano de consulta incorreto, consulta incorreta ...)

manlio
fonte
24

É possível gravar E / S assíncronas onde você diz ao sistema operacional para despachar uma leitura / gravação em disco e, em seguida, faz outra coisa e depois verifica se está pronto. Está longe de ser novo. Um método mais antigo está usando outro encadeamento para o IO.

No entanto, isso requer que você tenha algo para fazer enquanto essa leitura estiver sendo executada e você não poderá tocar no buffer que você transmitiu para o resultado.

Também é muito mais fácil programar quando você assume que tudo está bloqueando o IO.

Quando você chama uma função de leitura de bloqueio, sabe que ela não retornará até que algo tenha sido lido e imediatamente após o início do processamento.

O loop de leitura típico é um bom exemplo

//variables that the loop uses
char[1024] buffer;
while((read = fread(buffer, 1024, 1, file))>0){
    //use buffer
}

Caso contrário, você precisará salvar o estado atual da função (geralmente na forma de um retorno de chamada + ponteiro userData) e passá-lo + identificador da operação de leitura de volta para um select()loop de tipo. Lá, se uma operação for concluída, ele mapeará o identificador da operação de leitura para o ponteiro de retorno de chamada + dados e invocará o retorno de chamada com informações da operação concluída.

void callback(void* buffer, int result, int fd, void* userData){
    if(result<=0){
    //done, free buffer and continue to normal processing
    }
    //use buffer

    int readID = async_read(fd, buffer, userData->buff_size);
    registerCallback(readId, callback, userData);
}

Isso também significa que todas as funções que poderiam acabar usando essa leitura assíncrona precisariam ser capazes de lidar com uma continuação assíncrona. Essa é uma mudança não trivial na maioria dos programas; você pergunta às pessoas que tentam entrar em C # assíncrono.


No entanto, E / S síncrona vs. E / S assíncrona não é a causa do abrandamento geral. A troca de páginas também é uma operação que precisa aguardar IO. O agendador alternará apenas para outro programa que não esteja aguardando IO se houver ( espera IO quando o processador estiver ocioso e houver uma operação pendente ).

O verdadeiro problema é que o disco rígido e a CPU usam o mesmo canal para se comunicar com a RAM ; o barramento de memória. E, a menos que você esteja usando RAID, haverá apenas um disco para obter os dados. Isso é piorado se você também estiver usando um aplicativo intensivo em gráficos, a comunicação com a GPU também interferirá.

Em outras palavras, o gargalo real provavelmente está no hardware e não no software.

catraca arrepiante
fonte
6
"No entanto, o IO síncrono versus o IO assíncrono não é a causa da desaceleração geral." Então, por que você decidiu se concentrar nesse tópico relativamente avançado quando a pergunta é sobre o básico?
svick 8/09/15
11
Você provavelmente deveria mencionar algo sobre DMA
Alec Teal
2
Curiosidade: na verdade, existe um mecanismo realmente antigo que permite que os programas façam outra coisa enquanto executam E / S sem ter que lidar com retornos de chamada; é chamado de threads .
user253751
2
Boa discussão sobre os prós / contras de E / S sincronizada / assíncrona. Mas você tem certeza de que esse é o motivo da desaceleração? Geralmente, acho que as lentidões sob uma carga pesada de E / S são, em primeiro lugar, devido a um software mal arquitetado, ou quando esse não é o caso, porque o sistema está usando um único disco lento (ou seja, não SSD) e tudo está tentando acessá-lo simultaneamente. . Eu culparia um gargalo pela capacidade do disco de atender a solicitações antes de culpar a saturação do barramento de memória. Você precisa de armazenamento realmente sofisticado para saturar um barramento de memória moderno.
Aroth 9/09/15
9

Acredite que o processamento de outras coisas enquanto aguarda a E / S é bastante simplificado, o mais próximo possível da simplificação. Quando você vê que seu computador aguarda E / S apenas 12,1% do tempo, significa que ele está fazendo muitas outras coisas em paralelo. Se realmente tivesse que esperar por E / S sem fazer mais nada, estaria aguardando 99,9% do tempo, é assim que a E / S era lenta.

A única maneira de fazer mais coisas em paralelo é prever o que o usuário pode querer fazer a seguir, e ainda não somos muito bons nesse tipo de previsão. Portanto, se o usuário executar uma operação que exija a leitura de um setor específico no disco rígido e esse setor ainda não estiver no cache, o sistema operacional iniciará o processo muito longo de leitura desse setor, e tentará ver se há mais alguma coisa a fazer nesse meio tempo. Se houver outro usuário que deseje um setor diferente, ele também enfileirará essa solicitação. Em algum momento, todas as solicitações foram enfileiradas e não há nada que possamos fazer além de esperar que a primeira seja satisfeita antes que possamos prosseguir. É apenas um fato da vida.

EDITAR:

Encontrar uma solução para o problema de como fazer outras coisas enquanto fazia E / S seria um feito admirável, porque ao mesmo tempo seria uma solução para o problema de como fazer outras coisas enquanto ocioso. Uma façanha incrível que seria, porque significaria que você encontraria trabalho para o seu computador, enquanto ele não possui nenhum.

Veja bem, é isso que está acontecendo: seu computador está apenas 99,99% do tempo sem fazer nada. Quando você dá algo para fazer, vai e faz. Se, ao fazê-lo, precisar esperar pela E / S, ficará lá e aguardará. Se houver mais alguma coisa a fazer durante a E / S, também o fará. Mas se ele não tiver mais nada a fazer além de E / S, precisará permanecer ali e aguardar a conclusão da E / S. Não há como contornar isso, além de se inscrever no SETI @ Home.

Mike Nakis
fonte
Bem, o exemplo de 12,1% era de um site e o exemplo foi tirado de um servidor com 8 núcleos, a ideia era que quase um núcleo inteiro era reservado apenas para essas operações, com certeza os outros núcleos estavam livres para fazer qualquer coisa e com 8 núcleos você está bem, mas e se você tiver apenas um núcleo? : /
Arturas M
3
@ArturasM Você entendeu mal o que o site está dizendo ou o autor do site não entendeu algo. Um computador com apenas um único núcleo gastaria menos tempo aguardando E / S (uma vez que todas as tarefas que não estão aguardando E / S, que estão sendo executadas nos outros núcleos enquanto um núcleo fica ocioso, teriam que ser executadas no único testemunho). A E / S leva uma certa quantidade de tempo para acontecer, independentemente de você esperar ou não - ter tempo para esperar é um sintoma de não ter mais nada a ver com esse tempo.
precisa saber é o seguinte
6

O sistema operacional (a menos que seja um sistema embarcado de nível muito baixo ou algo semelhante à exótico) já cuida disso: se seu aplicativo tiver que esperar por E / S, ele normalmente bloqueará essa E / S e algum outro encadeamento ou aplicativo se tornará ativo. O planejador decide qual deles.

Somente se não houver outro encadeamento ou aplicativo em execução, você estará acumulando tempo de espera. No artigo que você citou (graças a @manlio pelo link), esse é o caso: você tem 12,1% em espera versus 87,4% em ociosidade, o que significa que um núcleo está aguardando a conclusão da E / S enquanto o resto não está fazendo nada em absoluto. Dê a esse sistema algo para fazer, de preferência várias coisas, e a porcentagem de espera deve cair.

Um dos principais objetivos do design de aplicativos de hoje é garantir que, mesmo que haja apenas um aplicativo em execução, e mesmo que esse aplicativo esteja em algum momento aguardando E / S, o aplicativo ainda pode continuar em outro pedaço de trabalho. Os encadeamentos são uma abordagem para isso, a E / S não bloqueadora, mas depende muito do tipo de trabalho que você está realizando, se você pode realmente fazer alguma coisa sem os dados que está esperando.

ao usar o Linux, se você estiver executando algumas tarefas de E / S mais longas, o sistema operacional se tornará quase inutilizável até que sejam concluídas.

Isso geralmente é uma indicação de alguma situação ligada à E / S. Ouso dizer que o sistema não está ficando lento porque não pode processar bastante a CPU. Provavelmente é lento porque várias coisas dependem dos dados do disco rígido, que está ocupado naquele momento. Podem ser aplicativos que você deseja executar, mas que precisam carregar seus arquivos executáveis, arquivos de biblioteca, ícones, fontes e outros recursos. Podem ser aplicativos que você já possui em execução, mas que trocaram parte de sua memória e agora precisam dessa troca novamente para prosseguir. Pode ser algum daemon que, por um motivo ou outro, acha que não apenas precisa escrever uma linha em um arquivo de log, mas também liberá-lo antes de responder a uma solicitação.

Você pode usar ferramentas como iotoppara ver como a capacidade de E / S é alocada para processos e ionicedefinir prioridades de E / S para processos. Por exemplo, em uma máquina de mesa, você pode classificar todo o processamento de dados em massa comoidle classe de agendamento, para que, no momento em que algum aplicativo interativo precise de largura de banda de E / S, o processamento em massa seja suspenso até que o aplicativo interativo seja concluído.

MvG
fonte
5

Depende do código do seu aplicativo. Suponho que seu código esteja sendo executado no Linux.

Você pode usar o multiencadeamento (por exemplo, POSIX pthreads ) para que os encadeamentos vinculados à computação façam alguma computação enquanto outros encadeamentos vinculados ao IO fazem o IO (e aguardam). Você pode até ter seu aplicativo executando vários processos se comunicando com a comunicação entre processos (IPC), consulte pipe (7) , fifo (7) , soquete (7) , unix (7) , shm_overview (7) , sem_overview (7) , mmap (2) , eventfd (2) e leitura Programação avançada do Linux, etc ....

Você pode usar E / S sem bloqueio , por exemplo, passe O_NOBLOCKpara abrir (2) etc etc etc ...; então você precisará pesquisar (2) e / ou usar o SIGIO sinal (7) ... e manipular o EWOULDBLOCKerro de read (2) etc ...

Você pode usar E / S assíncrona POSIX, consulte aio (7)

Para acesso ao arquivo, você pode dar dicas ao cache da página , por exemplo, com madvise (2) depois do mmap (2) e com posix_fadvise (2) ; veja também o readahead específico do Linux (2)

Mas você acabaria atingindo algum gargalo de hardware (o barramento, a RAM, etc ...). Veja também ionice (1)

Basile Starynkevitch
fonte
1

Eu adiciono outro ponto de vista que outros, talvez controverso:

É um problema típico dos sistemas operacionais Linux. Atrasando especificamente (procure por "Linux mouse lag"). O Windows não tem esse problema. Eu tenho inicialização dupla do Windows 7 e Linux Mint. Mesmo ao realizar operações intensivas de disco no Windows, o Windows parece suave, o mouse está se movendo normalmente. No Linux, ao contrário, não parece tão suave e o mouse às vezes fica atrasado, mesmo durante a navegação normal na web.

Provavelmente por causa da filosofia e história diferentes desses dois sistemas. Desde o início, o Windows foi projetado para usuários comuns, seus sistemas de operações principalmente gráficos. E para usuários do Windows, o comportamento não suave do sistema e a interrupção do mouse são sinais de que algo está errado. Portanto, os programadores da Microsofts trabalharam duro para projetar todo o sistema para minimizar os casos em que os sistemas pareciam lentos. Em outro lado, o Linux não é um sistema gráfico inicialmente, o desktop é apenas uma adição de terceiros aqui. E o Linux é projetado principalmente para hackers usando linha de comando. Faça as coisas como filosofia. O Linux simplesmente não foi projetado para ter um comportamento tranquilo, sentimentos não importam aqui.

Nota: Não estou dizendo que o Windows é melhor que o Linux; digo que eles simplesmente têm uma filosofia geral diferente, que em ambientes complexos pode levar a comportamentos / sentimentos de alto nível diferentes desses sistemas.

user3123061
fonte
O atraso do mouse no Linux provavelmente poderia ser evitado ou diminuído pela configuração cuidadosa do sistema (ou seja, usando nice& ioniceem processos com fome). E eu uso Linux e quase nunca experimentaram que o Linux rato lag (exceto quando sobrecarregar meu computador ...)
Basile Starynkevitch
BTW, o Linux é principalmente um sistema operacional de servidor.
Basile Starynkevitch
Observarei que experimentei um atraso na interface do usuário e no mouse no Windows 7, mesmo nos momentos em que o Gerenciador de Tarefas e o Monitor de Recursos indicavam pouco uso de memória e baixa atividade de CPU e disco.
8bittree