Revista Linux Magazine

Page 1

PROGRAMAÇÃO

Novidades e benchmarks do GCC 4.1

Teste de vôo A nova versão do compilador GNU (GCC) vem com uma safra novíssima de otimizações e suporte a Objective-C++. O parser descendente introduzido na versão 4.0 agora é usado para C e Objective-C. por René Rebe

O

GCC 4.1 foi lançado com um atraso de apenas uma semana [1]. O Release Manager Mark Mitchell foi forçado a adiar um pouco a data do lançamento para incluir o suporte a pontos flutuantes de 128 bits na arquitetura PowerPC, pois esse é um recurso importante da futura Glibc.

Parser manual

Uma das mudanças profundas é o uso do parser de C++ da última versão do GCC agora também para C e ObjectiveC. O parser recursivo descendente escrito manualmente (isto é, não foi escrito com um gerador de parsers tradicional como o Bison ou o Yacc) é mais rápido, e espera-se que seja mais fácil de manter a longo prazo. A Apple acrescentou a capacidade de misturar Objective-C com C++ ao GCC do MacOS X há algum tempo. Objective-C é uma alternativa ao C++ que oferece orientação a objetos com uma sintaxe que lembra a do Smalltalk, junto com tipagem dinâmica e introspecção. Porém, faltam-lhe estruturas modernas do C++, como templates e namespaces. O Objective-C++ agora oferece a possibilidade de misturar características de C++ com Objective-C, ou simplesmente utilizar bibliotecas C++ com código Objective-C. Os desenvolvedores do GCC integraram o protetor de stack smashing (Stack Smashing Protector, ou SSP), desenvolvido

74

pela IBM e disponível há algum tempo como patch [2]. Programas compilados com suporte a SSP mudam a ordem das variáveis na pilha para evitar a manipulação maliciosa ou inadvertida. O SSP permite que os programadores criem funções para detectar estouros de buffer. Os programadores do GCC ainda estenderam consideravalmente a biblioteca Java que implementa importantes aspectos da API do Java, incluindo o conjunto de ferramentas gráficas AWT e o Swing. Os aplicativos Java sozinhos compõem mais de um terço do Changelog [3]. O GCJ e o GNU Classpath suportam a compilação do ambiente de desenvolvimento Eclipse, escrito em Java, sem qualquer modificação no código. As novas otimizações, baseadas na infraestrutura Tree SSA introduzida na versão 4.0, agora funcionam além dos limites das funções. Isso oferece um esquema mais confiável para a detecção de pedaços de código não utilizados, candidatos a inlining, e variáveis completamente removidas pelas otimizações. Os desenvolvedores também melhoraram a vetorização automática, que mapeia laços em unidades de vetores, como SSE (Intel/AMD) e Altivec (PowerPC).

Velharias

Assim como nas versões anteriores, as extensões GNU foram retiradas das linguagens padronizadas para garantir uma grande portabilidade dos aplicativos para

diversas plataformas e compiladores. Dessa vez, declarações friend em classes foram limadas na limpeza: struct a { friend void f() { ... } };

No GCC 4.1 os programadores C++ devem definir uma função friend em conformidade com os padrões fora da classe: struct a { friend void f(); } void f() { ... }

Namespaces superespecificados (extra qualification), usados em muitos programas em C++, são outra vítima, como demonstrado pelo programador do Debian Martin Michlmayr em [4]. class b { void b::f (); };

O compilador GNU agora retorna um erro: error: extra qualification ‘b::’ on member ‘f’. Neste exemplo, é necessário apagar o b:: na frente dos métodos da classe.

http://www.linuxmagazine.com.br


GCC | PROGRAMAÇÃO

Botan 3.4.0-O0 4.0.0-O0 4.1.0-O0 3.4.0-O1 4.0.0-O1 4.1.0-O1 3.4.0-Os 4.0.0-Os 4.1.0-Os 3.4.0-O2 4.0.0-O2 4.1.0-O2 icc9.0-O2 4.0.0-O2-loops 4.1.0-O2-loops 4.0.0-O2-rename-reg 4.1.0-O2-rename-reg 4.0.0-O2-tracer 4.1.0-O2-tracer 4.0.0-O2-vect 4.1.0-O2-vect 3.4.0-O3 4.0.0-O3 4.1.0-O3 4.0.0-O3-loops 4.1.0-O3-loops 4.0.0-O3-rename-reg 4.1.0-O3-rename-reg 4.0.0-O3-tracer 4.1.0-O3-tracer 4.0.0-O3-vect 4.1.0-O3-vect

Figura 1

Bzip2 209.64 226.50 230.15

35.70 29.46 29.15 28.30 28.55 29.85 29.13 28.27 28.68 28.54 27.89 26.71 29.02 28.26 29.12 28.44 28.46 28.40 28.37 28.43 27.40 26.69 28.58 27.76 28.74

Gnupg 32.99 34.83 34.71

Gzip 21.25 21.73 23.05

Lame

OpenSSL

25.32 26.91 26.86

210.95 236.93 236.45

Tramp3d 7.56 6.77 6.78

249.80 296.70 232.79

13.56 14.46 14.71 13.18 12.73 13.28 13.39 13.66 13.91 13.15

11.91 11.24 10.78 10.66 11.35 11.14 12.02 12.36 11.68 13.86

10.67 9.49 10.52 9.62 10.87 12.31 9.82 9.50 9.26 9.69

88.74 91.51 91.20 88.04 90.89 91.71 83.25 86.36 86.71 81.93

2.33 2.11 1.98 2.10 2.12 2.03 2.10 2.07 1.99 2.16

23.00 8.95 7.18 12.97 91.33 19.66 13.73 8.66 6.46

13.24 13.16 12.95 13.35 13.39 13.71 13.52 13.87 12.05 12.89 13.61 12.95 13.04 12.66 13.34 13.37 13.61 13.32

10.60 11.54 12.36 10.46 10.62 11.01 10.45 10.38 12.22 11.40 10.12 12.00 10.36 10.62 11.15 11.67 10.26 10.49

9.22 9.61 9.30 9.19 9.31 9.38 9.46 9.43 9.66 9.85 9.16 9.30 9.09 9.89 9.18 9.54 9.11 10.01

86.08 83.86 85.64 86.19 86.51 87.24 88.12 87.04 82.12 86.55 87.08 84.08 83.40 84.90 85.67 86.70 86.80 87.86

2.04 1.92 2.02 1.95 2.05 1.99 2.08 2.01 1.92 2.05 1.97 2.02 1.92 2.02 1.92 2.05 1.95 2.08

5.80 4.21 8.13 6.34 8.16 6.46 8.39 6.62 13.84 8.21 4.49 5.75 4.30 8.06 4.25 8.03 4.50 8.45

10.05

9.34

86.14

1.98

4.66

28.44 13.82 (in seconds – smaller is better)

Tempos de execução em diversos cenários de compilação.

Velocidade

Como em meus artigos anteriores sobre o compilador GNU, novamente eu usei o Openbench para descobrir como o compilador atual se compara a seus antecessores (veja a caixa Benchmarks). Como muitos outros desenvolvedores de código aberto têm interesse num benchmark livre com propriedades semelhantes às do SPEC, já antecipo que uma versão inicial de referência do Openbench será paralizada este ano para comparações futuras. Seus comentários e ajuda são bem-vindos. Por sugestão de vários leitores, medi o tempo com -O0, embora isso torne os diagramas mais dinâmicos. As novas versões do GCC compilam muito mais

Benchmarks Para os benchmarks, foi usada a coleção de benchmarks Openbench, referida em artigos anteriores publicados nesta revista. O Openbench agora fez oficialmente a lista de benchmarks na página do GCC [8]. Eu tive que mudar algumas coisas: atualizei o Botan novamente para a versão mais recente, 1.4.12, e substituí o teste do libmad, que tem resultados muito semelhantes em compiladores diferentes, pelo codificador de MP3 de código aberto Lame.

Linux Magazine #22 | Agosto de 2006

rápido se a otimização for desativada. valor for mudado quando o programa O -O0 é particularmente útil no ciclo sair da função, pode-se presumir que de edição-e-compilação durante o de- o endereço de retorno também foi sosenvolvimento. O sistema Athlon que brescrito – esta é uma técnica comueu usava antes agora foi trocado por um mente utilizada por hackers e softwaAMD64 Turion64. res mal intencionados. Nesse caso, o O efeito mais óbvio pode ser visto programa imprime um aviso e sai. Se nos testes com Botan e o Tramp3d, em você compilar e executar o programa C++: 25% mais rápido com o O2 e mais do exemplo 1, verá uma mensagem de de 40% com o O3, no caso do Botan. Os erro dizendo *** stack smashing detecresultados com código C antigo estão ted ***: ./ssp-test terminated. ➧ bem misturados (veja a figura 1). Se você olhar os tempos de compiExemplo 1: ssp-text.c lação (figura 2), verá quanto trabalho a mais o compilador realiza se a oti01 int f () { 02 char a [200]; mização for pedida. E o esforço nem 03 char* b = a; sempre se reflete em influência positiva 04 int i; sobre o tempo de execução. Podemos 05 for (i=0; i<201; ++i) ficar otimistas pois ao menos o exigente 06 a[i] = i; benchmark C++ Tramp3d foi compila07 } 08 do mais rapidamente pela versão 4.1 do 09 int main () { que pela anterior.

SSP

Como dito antes, o SSP da IBM deixa o programador detectar estouros e esvaziamentos de buffer (buffer underflows). Para tanto, põe um valor aleatório de /dev/urandom ou, caso não haja um disponível, a cadeia de caracteres \0\xFF\n, em algum lugar próximo ao endereço de retorno da pilha. Se esse

10 f (); 11 }

Exemplo 2: mudflap-test.c 01 int main () { 02 char a [200]; 03 char* b = a; 04 printf (“%c\n”, b[200]); 05 }

75


PROGRAMAÇÃO | GCC

Botan 3.4.0-O0 4.0.0-O0 4.1.0-O0 3.4.0-O1 4.0.0-O1 4.1.0-O1 3.4.0-Os 4.0.0-Os 4.1.0-Os 3.4.0-O2 4.0.0-O2 4.1.0-O2 icc9.0-O2 4.0.0-O2-loops 4.1.0-O2-loops 4.0.0-O2-rename-reg 4.1.0-O2-rename-reg 4.0.0-O2-tracer 4.1.0-O2-tracer 4.0.0-O2-vect 4.1.0-O2-vect 3.4.0-O3 4.0.0-O3 4.1.0-O3 4.0.0-O3-loops 4.1.0-O3-loops 4.0.0-O3-rename-reg 4.1.0-O3-rename-reg 4.0.0-O3-tracer 4.1.0-O3-tracer 4.0.0-O3-vect 4.1.0-O3-vect

Bzip2

106.80 94.02 95.98

Gnupg

2.23 2.35 2.38

156.91 141.38 183.61 193.57 60.30 63.76 198.22 165.72 99.01 76.35 103.32 168.43 236.07 171.01 238.54 166.87 234.50 93.44 78.25 104.89 81.48 109.67 180.12 248.32 178.12 252.00 177.04 247.40 (in seconds – smaller is better)

Gzip

16.46 17.09 17.14

2.87 3.77 4.55 4.48 3.90 4.34 5.09 5.62 6.17 5.36

23.48 27.05 29.16 30.25 31.77 33.33 33.56 35.82 36.66 32.90

6.16 7.06 5.45 6.13 5.49 6.17 5.89 6.43 5.79 6.13 7.05 7.74 7.97 6.25 7.15 6.26 7.17 6.79 7.45

Lame

1.06 1.12 1.16

38.10 41.98 35.96 37.66 35.02 37.42 35.76 38.24 36.13 37.01 40.57 42.20 47.05 38.18 41.61 38.90 41.32 39.10 43.59

OpenSSL

14.90 15.04 15.25

1.56 2.01 2.17 1.86 2.19 2.35 2.15 2.64 2.67 2.07 3.40 3.64 2.48 2.70 2.54 2.77 2.56 2.82 2.40 2.83 3.22 3.80 4.18 2.88 3.25 2.97 3.28 3.02 3.37

Tramp3d

74.05 76.13 74.85

19.09 21.84 23.51 23.46 23.77 25.54 24.68 28.14 29.90 29.32

88.40 98.03 100.46 98.96 104.91 108.28 109.39 118.50 117.30 118.61

35.60 38.54 28.57 30.16 28.54 30.45 29.78 31.78 26.88 30.80 35.95 38.77 43.08 30.91 36.08 31.95 36.19 32.70 37.73

120.06 125.88 115.84 118.95 116.25 117.98 117.78 121.03 112.72 116.92 123.19 124.95 130.84 119.53 124.97 118.46 123.72 121.69 127.30

28.12 35.63 35.46 50.41 110.11 87.50 68.16 43.36 42.60 74.60 139.78 108.59 144.44 115.81 134.40 109.20 136.12 110.14 141.35 112.31 73.52 142.56 117.28 153.54 123.62 144.09 117.92 145.33 119.48 150.60 121.95

Figura 2 Tempos de compilação para vários cenários de compilação.

O aviso dificulta a injeção de código mal intencionado por atacantes na forma de scripts. O parâmetro de linha de comando do GCC -fstack-protector ativa essa proteção.

algumas verificações desnecessárias. Na execução, as funções fornecidas pela biblioteca Libmudflap validam esse acesso, terminando o programa em casos críticos. A Libmudflap também valida muitas funções C padrão capazes de sobrescrever a memória, incluindo mem*, str*, *put*, *get* e diversas outras. Para usar o Mudflap, Uma técnica introduzida no GCC 4.0 todos os arquivos devem ser compilados leva a proteção um passo adiante em com a opção -fmudflap e linkados com relação ao SSP, ativando a validação a -lmudflap. O pequeno programa em C de referências a ponteiros em C e C++. para teste da exemplo 2 simplesmente Durante a compilação, esse mecanismo, acessa a posição de memória um byte conhecido como Mudflap, faz o acesso à além dos limites do vetor a. O Mudflap memória refletir o tipo de acesso (acesso aponta corretamente o nome da variável a campo ou de-referenciamento a pon- que passou dos limites (exemplo 3). teiro) e as condições que o compilador Como o Mudflap valida o acesso à detectar nesse momento. Por exemplo, memória em muitos casos, ele pode afea propagação de constantes pode tornar tar consideravelmente o desempenho em comparação com o SSP, o qual é quase imperceptível. Assim, o Exemplo 3: Saída do Mudflap Mudflap é principalmente útil para desenvolvedores interessamudflap violation 1 (check/read): time=1143457945.900790 dos em um método rápido de ptr=0x7fffffffae78 size=1 pc=0x2aaaaabcd2c1 location=`mudflap-test.c:6 (main)’ detectar erros potencialmente /usr/lib64/libmudflap.so.0(__mf_check+0x41) [0x2aaaaabcd2c1] críticos em estágios iniciais de ./mudflap-testt(main+0xd1) [0x4009f9] desenvolvimento.

Mudflap

01 02 03 04 05 06 07 08 09 10 11 12

/lib64/libc.so.6(__libc_start_main+0xf4) [0x2aaaaae8bea4] Nearby object 1: checked region begins 1B after and ends 1B after mudflap object 0x603c20: name=`mudflap-test.c:4 (main) a’ bounds=[0x7fffffffadb0,0x7fffffffae77] size=200 area=stack check=0r/0w liveness=0 alloc time=1143457945.900783 pc=0x2aaaaabcc711 number of nearby objects: 1

76

Futuro

Os diversos projetos externos programados para a integração com o GCC 4.2 [6] incluem o

suporte a OpenMP [7] e extensões das linguagens C, C++ e Fortran para suportar paralelização explícita. Estes projetos objetivam eliminar o buraco que se abriu entre a coleção de compiladores livres e os compiladores comerciais. ■

Mais Informações [1] Homepage do GCC: http:// gcc.gnu.org/ [2] Stack Smashing Protector SSP: http://www.trl.ibm.com/ projects/security/ssp/ [3] Mudanças no GCC 4.1: http://gcc.gnu.org/gcc-4.1/ changes.html [4] Compilando o Debian com o GCC 4.1 – relato de experiência:

http://gcc.gnu.org/ml/ gcc/2006-03/msg00740.html [5] Mudflap: http://gcc.fyxm.net/ summit/2003/mudflap.pdf [6] GCC 4.2: http://gcc.gnu.org/ wiki/GCC%204.2%20Projects [7] OpenMP: http://www.openmp.org/ drupal/mp-documents/spec25.pdf [8] Openbench: http://www.exactcode.de/ oss/openbench/

http://www.linuxmagazine.com.br



Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.