Profile-guided optimization

4 views
Skip to first unread message

Gianni

unread,
Nov 27, 2009, 6:00:21 AM11/27/09
to ccppb...@googlegroups.com
Estou curioso para saber se alguém aqui já comparou compiladores para ver qual
gera o código mais rápido. É claro que isso é uma pergunta bem complexa e
pode significar um monte de coisa diferente... eu estou curioso por todos os
aspectos disso.

Eu uso principalmente o GCC, para plataformas ARM, MIPS32, SuperH4 e x86_64 é
claro. Uso eles principalmente em Linux, mas tambem muito em OS X e FreeBSD.

A minha dúvida é como otimizar meu código para que rode mais rápido. Tenho
umas 'boas praticas' tipo use flags '-O3 -fomit-frame-pointer -
fvisibility=hidden' c/ um belo 'strip' depois. Tem coisas que eu nunca
cheguei a fazer em um 'caso real' mas me parecem ajudar bastante, como por
exemplo Profile-guided optimization:

http://jasondclinton.livejournal.com/70872.html

ou então comparar um projeto compilando funções como inline vs
__attribute__((pure)) ou usar '-std=c++0x'

Uso o Valgrind/calgrind de vez em quando para ver onde devo investir mais
tempo também:

http://kcachegrind.sourceforge.net/html/Shot3Large.html


Mas e vcs? Alguem já comparou GCC c/ Profile-guided vs LLVM por exemplo? Tem
alguma dica? Alguma mágia negra ou simpatia p/ rodar mais rápido?


Notem por favor que eu pergunto do binário gerado rodar mais rápido; não me
importa qual compilador compila mais rápido. Afinal, isso já é outro problema
para distcc, etc...

Ronaldo Faria Lima

unread,
Nov 28, 2009, 7:13:36 PM11/28/09
to ccppb...@googlegroups.com
Olá, Gianni.

Ao longo dos anos eu me tornei muito pragmático com relação aos
otimizadores. O ganho que você vai conseguir entre um ou outro será
tão ínfimo que não vale a pena gastar energia com isso. Eu acredito
que é melhor melhorar a performance do seu software otimizando suas
rotinas do que gastar energia otimizando os binários.

Bem, desculpe pelo off-topic. Eu tive experiências com essa comparação
entre diversas plataformas unix e o ganho sempre foi muito ínfimo. Não
justificava-se o esforço.

Por outro lado, a experiência demonstrou que normalmente os
compiladores fabricados pelos mesmos fabricantes dos processadores ou
plataforma sempre geravam código um pouco mais ótimo do que os
genéricos. Por exemplo, no Solaris, o compilador do Workshop, da Sun,
gera código muito mais otimizado que o compilador GNU, que é um
compilador geral. Via de regra, o GCC e as ferramentas da GNU, geram
um bom código binário mas não tão otimizado quanto os compiladores das
plataformas.

Espero ter ajudado.

Ronaldo

2009/11/27 Gianni <nasus....@gmail.com>:

zimbrao

unread,
Nov 29, 2009, 1:14:36 PM11/29/09
to ccppbrasil
Gianni,

Há casos e casos. O compilador Intel tem fama de otimizar bastante,
mas sem procurar muito vc encontra situações onde o g++ gera um código
mais rápido... e assim por diante!

Mas uma coisa muito importante para deixar o otimizador, qualquer que
seja, trabalhar bem, é passar pra ele toda a informação disponível:
por exemplo, se uma variável/ponteiro/referência não será modificada
devemos utilizar const etc.

No mais, normalmente o que mais dá resultado é usar os algoritmos mais
adequados. Por melhor que seja o otimizador, ele não vai transformar
um bubble-sort em quick-sort...


[]s
--
================================
Geraldo Zimbrão
Professor Adjunto - DCC/Coppe/UFRJ
www.zimbrao.com
www.cos.ufrj.br/~zimbrao

Felipe Magno de Almeida

unread,
Nov 29, 2009, 1:27:19 PM11/29/09
to ccppb...@googlegroups.com
2009/11/29 zimbrao <zim...@gmail.com>:

>
> Gianni,
>
> Há casos e casos. O compilador Intel tem fama de otimizar bastante,
> mas sem procurar muito vc encontra situações onde o g++ gera um código
> mais rápido... e assim por diante!
>
> Mas uma coisa muito importante para deixar o otimizador, qualquer que
> seja, trabalhar bem, é passar pra ele toda a informação disponível:
> por exemplo, se uma variável/ponteiro/referência não será modificada
> devemos utilizar const etc.

Na verdade const raramente pode ser utilizado como forma de otimização.
A unica forma de otimização mais reliable é a de possibilitar colocar
um objeto em um espaço de memória read-only, como por exemplo uma ROM,
já que modificar um objeto definido como const é undefined-behavior.
Porém, isto é perfeitamente legal:

TU 1:
-- A.hpp --
struct A { int x; };

int f(A const&);
-- main.cpp --
int main()
{
A a = {5};
f(a); // recebe por referencia constante
// O compilador não pode fazer a asserção de que a.x == 5 aqui
// pois ele nao tem como provar que A nao foi modificado em f, mesmo
// tendo sido passado como referencia constante.
}

-
TU2
-- A.h --
struct A { int x; }

int f(A const&);
-- A.cpp --
int f(A const& a)
{
const_cast<A&>(a).x = 4; // perfeitamente legal
}
--

PS: O mesmo não vale pra se A fosse definido como const. Neste caso
executar f implicaria em undefined behavior.

O compilador só pode fazer constant folding se ele puder provar que
não há modificação alguma do objeto (ou se uma possivel modificação
implicasse undefined behavior), o que só é possivel tendo conhecimento
de todo o código sendo executado, com ou sem const.

[snip]

--
Felipe Magno de Almeida

Rodrigo Strauss

unread,
Nov 29, 2009, 7:52:29 PM11/29/09
to ccppb...@googlegroups.com
Não sei quanto ao GCC, mas eu já vi o PGO do Visual C++ fazer
verdadeiros milagres, como programas que ficam 2x mais rápidos
(programa server com boost::asio). Não custa tentar.

Rodrigo Strauss
http://www.1bit.com.br

2009/11/28 Ronaldo Faria Lima <ronaldo.f...@gmail.com>:
Reply all
Reply to author
Forward
0 new messages