Pergunta

Eu queria saber se alguém tinha algum número difícil no desempenho do código ARM vs Thumb no iPhone 3GS. Especificamente para o código de ponto não flutuante (VFP ou neon) - estou ciente dos problemas com o desempenho do ponto flutuante no modo de polegar.

Existe um ponto em que o tamanho extra do código das instruções maiores do braço se torna um perigo de desempenho? Em outras palavras, se meu código executável for relativamente pequeno em comparação com a memória disponível, existe algum medido Diferença de desempenho para ativar o modo de polegar?

A razão pela qual peço é que, embora eu possa ativar o ARM para os arquivos de origem específicos de neon no Xcode usando a opção "-marm", isso quebra a compilação do simulador porque o GCC está construindo x86. Eu queria saber se deveria desligar "compilar como polegar" e terminar com isso.

Foi útil?

Solução

Eu não sei sobre o iPhone, mas uma declaração geral de que o polegar é mais lento que o braço não está correto. Dada a memória do estado de espera zero de 32 bits, o polegar será um pouco mais lento, números como 5% ou 10%. Agora, se é o Thumb2 que é uma história diferente, diz -se que o Thumb2 pode correr mais rápido, não sei o que o iPhone tem meu palpite é que não é o Thumb2.
Se você não estiver ficando sem a memória de 32 bits do Estado zero, seus resultados variam. Uma grande coisa é a memória de 32 bits. Se você estiver correndo em um ônibus de 16 bits como a família Gameboy Advance, e há alguns estados de espera nessa memória ou ROM, o polegar pode facilmente sair para o desempenho para obter desempenho, mesmo que sejam necessárias mais instruções para executar a mesma tarefa.

Teste seu código! Não é difícil inventar um teste que forneça os resultados em que você está interessado ou não. É tão fácil mostrar que o braço sopra o polegar, pois é o polegar sopra o braço. Quem se importa com o que são os Dhrystones, é a rapidez com que ele executa seu código hoje que importa.

O que encontrei ao longo dos anos no desempenho do código de teste para o ARM é que seu código e seu compilador são o grande fator. Portanto, o polegar é um pouco mais lento em teoria, porque usa algumas por cento mais instruções para fazer a mesma tarefa. Mas você sabia que seu compilador favorito poderia ser horrível e, simplesmente, trocando de compiladores, você pode correr várias vezes mais rápido (o GCC se enquadra nessa categoria)? Ou usando o mesmo compilador e mistura as opções de otimização. De qualquer maneira, você pode sombrear a diferença de braço / polegar sendo inteligente sobre o uso das ferramentas. Você provavelmente sabe disso, mas ficaria surpreso ao saber quantas pessoas pensam que a única maneira de saber como compilar o código é a única maneira e a única maneira de obter melhor desempenho é lançar mais memória ou outro hardware no problema.

Se você está no iPhone, ouço que essas pessoas estão usando LLVM? Gosto do conceito de LLVM de várias maneiras e estou ansioso para usá-lo como meu motorista diário quando amadurece, mas achei produzir código de 10 a 20% (ou muito mais) mais lento para a tarefa específica que eu estava fazendo. Eu estava no modo de braço, não tentei o modo polegar e tinha um cache L1 e L2. Se eu tivesse testado sem os caches para realmente comparar o polegar com o braço, provavelmente veria o polegar alguns por cento mais lento, mas se você pensar nisso (do qual eu não estava interessado na época), você poderá armazenar o dobro do código do Thumb que o código do braço que o ARM que Pode sugerir que, embora haja alguns por cento mais de código geral para a tarefa, ao armazenar em cache significativamente mais e reduzir o tempo médio do tempo de busca pode ser visivelmente mais rápido. Posso ter que tentar isso.

Se você estiver usando o LLVM, terá o outro problema de vários lugares para executar otimizações. Indo de C para Bytecode que você pode otimizar, você pode otimizar o próprio bytecode, então mesclado todo o seu bytecode e otimizando isso como um todo; depois, ao passar do código de byte para o assembler, você pode otimizar. Se você tivesse apenas três arquivos de origem e assumiu que havia apenas dois níveis de otimização por oportunidade, aqueles que não são otimizados ou otimizam, com o GCC, você teria 8 combinações para testar, com LLVM, o número de experimentos é quase uma ordem de magnitude mais alta . Mais do que você pode realmente correr, centenas a milhares. Para o teste que eu estava em execução, não opimizando na etapa C para ByteCode, não otimizando o bytecode enquanto separado, mas otimizando após a fusão dos arquivos bytecode em um grande (ger) um. A LLC otimiza no caminho para o ARM produziu os melhores resultados.

Resumindo ... teste, teste, teste.

EDITAR:

Eu tenho usado a palavra bytecode, acho que o termo correto é bitcode no mundo LLVM. O código nos arquivos .bc é o que quero dizer ...

Se você estiver indo de C para o braço usando LLVM, há Bitcode (BC) no meio. Existem opções de linha de comando para otimizar na etapa C a BC. Depois que o BC você pode otimizar por arquivo, BC para BC. Se você escolher, pode mesclar dois ou mais arquivos BC em arquivos BC maiores ou apenas transformar todos os arquivos em um grande arquivo BC. Em seguida, cada um desses arquivos combinados também pode ser otimizado.

Minha teoria, que tem apenas alguns casos de teste por trás disso até agora, é que, se você não fizer nenhuma otimização até ter todo o programa/projeto em um grande arquivo BC, o otimizador tem o valor máximo se informações com as quais fazer seu trabalho. Então isso significa que vá de C a BC sem otimização. Em seguida, mescla todos os arquivos BC em um grande arquivo BC. Depois de ter tudo como um grande arquivo BC, deixe o otimizador executar sua etapa de otimização, maximizando as informações e, esperançosamente, a qualidade da otimização. Em seguida, vá do arquivo BC otimizado para o assembler de ARM. A configuração padrão para a LLC está com otimização, você deseja permitir essa otimização, pois é a única etapa que sabe como otimizar para o destino. As otimizações BC a BC são genéricas e não são específicas de destino (AFAIK).

Você ainda precisa testar, testar, testar. Vá em frente e experimente otimizações entre as etapas, veja se faz seu programa funcionar mais rápido ou mais lento.

Outras dicas

Consulte este PDF do ARM/Thumb para compensação de desempenho/tamanho de código/consumo de energia.

Seleção guiada por perfil de instruções de braço e polegar
- Departamento de Ciência da Computação, Universidade do Arizona por Rajiv Gupta

O código do polegar será essencialmente sempre mais lento que o braço equivalente. O único caso em que o código do polegar pode ser uma grande vitória de desempenho é se fizer a diferença entre o seu código se encaixar na memória ou cache no chip.

É difícil fornecer números exatos sobre as diferenças de desempenho, porque é totalmente dependente do que seu código realmente faz.

Você pode definir sinalizadores de compiladores por arquitetura no Xcode, o que evitaria quebrar a compilação do simulador. Consulte a documentação de configuração de construção do Xcode.

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