Pergunta

Você escreve uma função e, olhando para a montagem resultante, vê que ela pode ser melhorada.

Você gostaria de manter a função que escreveu, para facilitar a leitura, mas gostaria de substituir o compilador pelo seu próprio assembly.Existe alguma maneira de estabelecer uma relação entre sua função de linguagem de alto nível e o novo assembly?

Foi útil?

Solução

Se você estiver olhando para o assembly, é justo presumir que você tem um bom entendimento sobre como o código é compilado.Se você tiver esse conhecimento, às vezes é possível fazer a 'engenharia reversa' das alterações para o idioma original, mas geralmente é melhor não se preocupar.

As otimizações que você faz provavelmente serão muito pequenas em comparação com o tempo e o esforço necessários para fazer essas alterações pela primeira vez.Eu sugiro que você deixe esse tipo de trabalho para o compilador e vá tomar uma xícara de chá.Se as mudanças forem significativas e o desempenho for crítico (como, por exemplo, no mundo incorporado), então você pode querer misturar o código normal com o assembly de alguma forma, no entanto, na maioria dos computadores e chips, o desempenho geralmente é suficiente para evitar essa dor de cabeça.

Se você realmente precisa de mais desempenho, então otimize o código e não o assembly.

Outras dicas

Nenhum, suponho.Você rejeitou o trabalho do compilador em favor do seu próprio trabalho.Você também pode descartar a função que escreveu na linguagem compilada, porque agora tudo o que você tem é o seu assembler nessa plataforma.

Eu desaconselho fortemente esse tipo de otimização porque, a menos que você tenha certeza, por meio de criação de perfil e análise, de que realmente está fazendo a diferença.

Depende do idioma em que você escreveu sua função.Algumas linguagens como C são de nível muito baixo, traduzindo cada chamada de função ou instrução em instruções assembly específicas.Se você usou C, poderá substituir sua função por montagem embutida para melhorar o desempenho.

Outras linguagens de alto nível podem converter cada instrução em rotinas de macro ou outras chamadas mais complexas no lado do assembly.Certas otimizações (como recursão final, desenrolamento de loop, etc.) podem ser implementadas facilmente no lado da fonte, mas outras (como fazer uso mais eficiente do arquivo de registro) podem ser impossíveis (novamente, dependendo da linguagem e do compilador que você está usando). usando).

É difícil dizer que existe alguma relação entre a montagem modificada e a fonte que gerou a versão não modificada.Certamente confundirá as ferramentas de depuração:o conteúdo do registro não corresponderá mais às variáveis ​​de origem às quais deveriam corresponder.

Há vários lugares no código de processamento de pacotes onde examinei o assembly gerado e voltei para alterar o código-fonte original para melhorar o resultado.Reorganizar a fonte pode reduzir o número de ramificações, __attribute__ e argumentos do compilador podem alinhar pontos de ramificação e funções para reduzir perdas de I$.Em casos desesperadores, um pequeno assembly embutido pode ser usado, para que o binário ainda possa ser compilado a partir do código-fonte.

Algo que você pode tentar é separar sua função original em seu próprio arquivo e fornecer uma regra make para construir o assembler a partir daí.Em seguida, atualize o arquivo assembler com sua versão melhorada e forneça uma regra make para construir um arquivo objeto a partir do arquivo assembler.Em seguida, altere suas regras de link para incluir esse arquivo objeto.

Se você alterar apenas o arquivo assembler, ele continuará sendo usado.Se você alterar o arquivo de linguagem original de nível superior, o arquivo assembler será reconstruído e o arquivo objeto construído a partir da nova versão (não melhorada).

Isso proporciona um relacionamento entre os dois;você provavelmente deseja adicionar um comentário de aviso no topo do arquivo de linguagem de nível superior para avisar sobre o comportamento.Usar alguma forma de VCS lhe dará a capacidade de recuperar o arquivo assembler aprimorado se você cometer um erro aqui.

Se você estiver escrevendo um aplicativo compilado nativo em Visual C++, existem dois métodos:

  1. Use o __asm { } bloqueie e escreva seu montador lá.
  2. Escreva suas funções em MASM assembler, monte em .obj e vincule-o como uma biblioteca estática.Em seu código C/C++, declare a função com um extern "C" declaração.

Outros compiladores C/C++ têm abordagens semelhantes.

Nessa situação, você geralmente tem duas opções:otimizar o código ou reescrever o compilador.Não consigo ver onde quebrar o link entre a origem e a operação será a solução correta.

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