A pesquisa paralela acelera a depuração de viagem no tempo em 4x

By | Junho 17, 2022

Introdução

Um dos principais novos recursos do UDB e do LiveRecorder 6.8 é uma otimização chamada Pesquisa Paralela – ela usa vários núcleos de CPU para fornecer aceleração de até 4x durante a depuração ao longo do tempo.

Comparação comparativa da operação de operação longa, com e sem busca paralela

Neste artigo, descreveremos algumas das mágicas que tornam essa aceleração possível. Mas primeiro teremos que explicar alguns conceitos básicos …

Como funciona a depuração de viagem no tempo?

A solução de problemas durante a viagem no tempo permite que você depure seu instantâneo com precisão de software. Uma vez gravado, isso pode ser reproduzido para frente e para trás e sempre se comportará da mesma maneira. Você pode ver qualquer parte do estado do programa para qualquer linha de código (ou qualquer instrução) que tenha sido executada, permitindo diagnosticar rapidamente erros graves.

O programa de computador é muito semelhante a uma locomotiva ferroviária. Tem um caminho de execução (ou seja, traces) que seguirá naturalmente:

O truque é que, ao interagir com o mundo exterior (por exemplo, obter informações dos usuários), esses caminhos podem se ramificar:

Artigo de pesquisa paralela - Locomotiva ferroviária 2

A tecnologia Undo registra todas as entradas recebidas pelo programa do mundo exterior – sejam elas óbvias (por exemplo, dados retornados por chamadas de sistema read()) ou menos óbvias (por exemplo, tempo preciso de sinais assíncronos ou dados lidos da memória compartilhada).

Não apenas podemos gravar isso, mas podemos reproduzi-lo para que o programa seja executado da mesma maneira, todas as vezes.

Usando instrumentação de código de máquina Just-In-Time, nosso mecanismo pode capturar com eficiência todos os locais onde um programa pode encontrar dados não determinísticos – nenhuma alteração de programa é necessária (nem mesmo recompilação).

Como funciona a execução reversa?

Para que possamos repetir as coisas – e elas sempre se comportarão da mesma forma. Mas como conduzir as coisas na direção oposta? Os computadores não podem funcionar ao contrário. Algumas operações como i++ são reversíveis. A maioria, no entanto, por exemplo, a = b não é – tudo o que era ua antes dessa tarefa se foi para sempre. (Na verdade, mesmo ++ nem sempre é reversível – considere o registrador de flag da CPU)

O segredo aqui é que o programa nunca funciona ao contrário. O algoritmo de “Pesquisa” no Undo Engine usa iteração determinística para fornecer efetivamente a ilusão de execução reversa.

  • Quando um usuário é solicitado a executar de trás para frente, ele está realmente se perguntando “qual aconteceu por último ? “. O evento de interesse pode ser a última vez que uma determinada linha de código foi iniciada (ponto de interrupção) ou a última vez que alguns dados foram alterados (ponto de observação).
  • Como podemos reproduzir a execução do programa, poderíamos responder a essa pergunta reiniciando todo o histórico de execução e anotando-o sempre que esse evento ocorrer. Em seguida, moveríamos a visualização do usuário de depuração para o evento anterior de interesse.
  • A desvantagem dessa abordagem seria que, mesmo quando não retrocedemos muito, ainda temos que tocar a gravação inteira.

Para tornar a execução reversa prática, o Undo Engine mantém as gravações do programa em momentos diferentes; pode pular imediatamente para o momento de qualquer tiro. Nosso algoritmo de busca é responsável por efetivamente entrar nesse histórico e encontrar a última vez que algo interessante aconteceu – nos dá a ilusão de rodar o código de trás para frente.

Pesquisa paralela de artigos - Vários processos de imagem

O processo de monitoramento “Nanny” do nosso mecanismo gerencia vários processos “Snapshot”, que representam diferentes pontos da história. A lacuna histórica entre os dois tiros é chamada de “fatia”

Nosso algoritmo divide o histórico em fatias – cada seção é um intervalo entre duas fotos. Ao reproduzir cada seção, começando com a mais recente e trabalhando de trás para frente, o Engine minimiza a quantidade de histórico que precisa ser reproduzida – se um ponto de interrupção ou ponto de vantagem for atingido durante uma seção recente, nenhum corte anterior deve ser verificado. Isso reduz significativamente o tempo necessário para pequenos passos para trás. (Observe que ainda precisamos verificar o restante desta parte caso haja uma correspondência melhor)

E os grandes passos para trás?

Esse algoritmo nos permite minimizar a quantidade de repetição necessária para executar na direção oposta – funciona especialmente bem quando damos um pequeno passo no passado.

Ao depurar sistemas do mundo real, muitas vezes é necessário retroceder o histórico por um longo tempo – você pode ter um trabalho de simulação e usar um ponto de vista para encontrar danos na memória do passado.

Quanto mais rápido pudermos viajar para o passado, mais rápido você poderá resolver seu bug.

Apresentamos uma pesquisa paralela

A pesquisa paralela estende nosso algoritmo de pesquisa existente usando vários núcleos de CPU para acelerar a execução reversa – com quatro núcleos de CPU, isso pode reduzir a latência a um fator de quatro. Isso significa que podemos rebobinar seu programa até 4x mais rápido do que o necessário para gravar.

Cada um dos cortes tocáveis ​​que compõem o histórico gravado começa com um instantâneo do estado do programa. Com qualquer um deles podemos prosseguir com a execução imediatamente. Também garantimos que o replay sempre terá o mesmo resultado, pois reproduzimos com precisão todas as operações não determinísticas: tudo está sobre trilhos, assim como nossa locomotiva.

Dado isso, não há razão para que não possamos executar vários cortes de forma independente, todos de uma vez – todos eles serão reproduzidos exatamente da maneira que originalmente fizeram. É exatamente isso que estamos fazendo agora.

Correndo para trás, em paralelo

Cada parte é uma parte independente da história do programa, então basicamente poderíamos executá-las todas de uma vez e depois escolher um vencedor.

Na prática, isso não seria o ideal: normalmente teremos mais cortes do que núcleos de CPU disponíveis. Nossa implementação programa os cortes seguidos que alimentam vários trabalhadores trabalhando em paralelo.

Pesquisa paralela de artigos - várias partes do histórico de execução em paralelo

Nosso mecanismo executa várias partes do histórico de execução em paralelo, permitindo cobrir a maior parte das filmagens em menos tempo.

  • Assim que qualquer trabalhador encontra uma correspondência, sabemos que os cortes anteriores não podem fornecer uma correspondência melhor. Poderíamos apenas deixá-los trabalhar até o fim, mas isso consome recursos do sistema e, se demorar muito, pode atrasar nossa resposta ao usuário.
  • Quando a seção encontrar um evento adequado, interromperemos todo o trabalho (incluindo o trabalho em andamento) nos cortes anteriores. Ainda estamos aguardando a conclusão de todos os clipes subsequentes – eles ainda podem fornecer eventos de interesse posteriores, que devemos relatar ao usuário.

Pesquisa paralela em UDB v6.8

No UDB e no LiveRecorder v6.8, limitamos o número de funcionários a um máximo de 4. Isso deve dar um bom impulso ao desempenho, ao mesmo tempo em que limita os custos indiretos. Esperamos aumentar isso no futuro, aproveitando sistemas maiores sempre que possível.

Nota: Depois de carregar o arquivo de gravação do LiveRecorder, o UDB pode exigir várias operações para aquecer o estado de gravação e obter o desempenho máximo.

Deixe uma resposta

O seu endereço de email não será publicado.