Archive for the ‘Baixo nível’ Category
Comparação de desempenho: std::vector vs Array
Comparação entre os códigos assembly gerados para operações de indexação básica, dereferenciação eincremento em std::vectors e arrays/ponteiros.
O código assembly foi gerado pelo gcc 4.1.0 chamado com g++ -03 -S em uma máquina x86_64-suse-linux.
#include struct S { int padding; std::vector v< int >; //nosso vector int * p; //nosso ponteiro std::vector< int >::iterator i; //iterador do vector }; int indexar_ponteiro(S & s) { return s.p[3]; } // movq 32(%rdi), %rax // movl 12(%rax), %eax // ret int indexar_vector(S & s) { return s.v[3]; } // movq 8(%rdi), %rax // movl 12(%rax), %eax // ret // Conclusão: Indexar um std::vector é a mesma coisa de indexar um ponteiro. int deref_ponteiro(S & s) { return *s.p; } // movq 32(%rdi), %rax // movl (%rax), %eax // ret int deref_iterador(S & s) { return *s.i; } // movq 40(%rdi), %rax // movl (%rax), %eax // ret // Conclusão: Dereferenciar um std::vector é a mesma coisa de dereferenciar um ponteiro. void incrementar_ponteiro(S & s) { ++s.p; } // addq $4, 32(%rdi) // ret void incrementar_iterador(S & s) { ++s.i; } // addq $4, 40(%rdi) // ret // Conclusão: Incrementar um iterador de std::vector é a mesma coisa de incrementar um ponteiro.
Ou seja, além das facilidades do std::vector, algumas operações básicas tem o mesmo custo tanto com std::vector quanto um array/ponteiro.
Surpreso?
Linguagens de Montagem Aula 5 – Memória
Segmentação
- Armazenamento de dados – escrever/ler
- Manutenção da pilha – escrever/ler
- Armazenamento de código – ler
Diretiva segment
Modo de uso:
segment .nome
Exemplo:
segment .data
segment .data
Indica o início de declarações pertencentes ao segmento de dados que contém somente dados inicializados.
Um pouco sobre números de ponto flutuante (floats e doubles)
Representação de números reais
Nos computadores atuais:
- É impossível a representação de números reais em computadores binários digitais porque a representação binária é discreta.
- Em qualquer linguagem de programação utilizamos representações que prevêem algum grau de arredondamento.
Antes de começar a falar de ponto flutuante vamos ver um pouco de ponto fixo.
Ponto fixo
Denotamos um número de ponto fixo quando especificamos o número de casas para a parte inteira e fracionária (matisse).
Exemplo: Ponto fixo 1.15 (Um bit para a parte inteira e quinze para a parte fracionária).
Na figura acima, podemos ver que reservei um bit para a parte inteira do número e 15 para a fracionária.
Dessa forma sempre teremos números menores que dois, pois como está reservado somente um bit para a parte inteira, o maior valor que esse bit pode valer é 1. A parte fracionária começa do 2^-1 e vai até o 2^-15. Esses valores são interpretados literalmente.
Por exemplo, o valor binário 1010 0000 0000 0000 corresponde a 2^0 + 2^-2 = 1.25.
Dessa forma, o menor número seria 0000 0000 0000 0000
E o maior: 1111 1111 1111 1111.