C++ Derleyicilerinde Optimizasyon: 2 – Compile Flag’leri

Derlenebilen dillerin bir çoğunda derleme zamanı problemleri yaşanmaktadır. C++ özellinde incelediğimiz zaman, proje büyüdükçe derleme zamanı geliştiriciler için çok büyük zaman kayıplarına yol açmaktadır. Hatta sadece compile-time’ı düşürmek için çalışan şirketler mevcuttur. Özellikle oyun endüstrisinde ortaya çıkan ürünlerin büyüklükleri yüzünde bu işlem oldukça vakit alır. Increbuild gibi şirketler bu işlemleri daha hızlı hale getirecek teknolojiler geliştirmektedir. Ben ise bu yazıda GCC üzerindeki optimizasyon flag’lerinden bahsetmeye çalışacağım.

Optimizasyon işlemi için compiler’lar kendi içlerinde flag’ler barındırır. Bu flag’ler ile çeşitli seviyelerde optimizasyon işlemi gerçekleştirmeniz mümkündür. GCC üzerinde optimizasyon işlemleri “-O” flag’i ile gösterilir ve optimizasyon seviyesine göre yanına farklı parametreler alır. -O ile başlayan optimizasyon işlemleri aslında -f ile başlayan ve spesifik olarak kontrol edilecebilecek olan işlemlerin grup halinde yapılabilmesini sağlamaktadır.

-O0

Tüm optimizasyon seviyeleri kapalıymış gibi işlem yapmanızı sağlar. Genellikle debug işleminin yoğun şekilde yapılacağı kodlarda daha hızlı compile-time sağlamak için tercih edilir. Kod içerisinde herhangi bir optimizasyon gerçekleşmediği için en hızlı optimizasyon seviyesi -O0’dır. Ancak kod boyutu ve kod içerisindeki işlem hızında en iyi seviyeyi sağlaması beklenmez. Bu yüzden ürün haline gelecek çıktılarda kullanılması önerilmez.

-O1

Çok fazla compile-time ve hafıza kullanımı yapmadan, aşağıdaki flag’leri aktif ederken en temel seviyede optimizasyon sağlar. Çoğu zaman tercih edilmesi hem kod boyutu hem de çalışma hızı bakımından tercih edilebilir.

-O1 ile birlikte otomatik olarak aktif hale gelen flag’ler:

-fauto-inc-dec
-fbranch-count-reg
-fcombine-stack-adjustments
-fcompare-elim
-fcprop-registers
-fdce
-fdefer-pop
-fdelayed-branch
-fdse
-fforward-propagate
-fguess-branch-probability
-fif-conversion
-fif-conversion2
-finline-functions-called-once
-fipa-modref
-fipa-profile
-fipa-pure-const
-fipa-reference
-fipa-reference-addressable
-fmerge-constants
-fmove-loop-invariants
-fmove-loop-stores
-fomit-frame-pointer
-freorder-blocks
-fshrink-wrap
-fshrink-wrap-separate
-fsplit-wide-types
-fssa-backprop
-fssa-phiopt
-ftree-bit-ccp
-ftree-ccp
-ftree-ch
-ftree-coalesce-vars
-ftree-copy-prop
-ftree-dce
-ftree-dominator-opts
-ftree-dse
-ftree-forwprop
-ftree-fre
-ftree-phiprop
-ftree-pta
-ftree-scev-cprop
-ftree-sink
-ftree-slsr
-ftree-sra
-ftree-ter
-funit-at-a-time

-O2

Kodun performansını ve kod güvenliğini artırmak için -O1’de belirtilen tüm flag’leri açmasının yanında aşağıdaki flag’leri de açar. Eğer özel bir optimizasyon işlemi gerçekleştirilmeyecekse ürünlerin Release versiyonları için önerilen ve en yeterli optimizasyon seviyesidir.

-O2 ile birlikte otomatik olarak aktif hale gelen flag’ler:

-falign-functions  -falign-jumps
-falign-labels  -falign-loops
-fcaller-saves
-fcode-hoisting
-fcrossjumping
-fcse-follow-jumps  -fcse-skip-blocks
-fdelete-null-pointer-checks
-fdevirtualize  -fdevirtualize-speculatively
-fexpensive-optimizations
-ffinite-loops
-fgcse  -fgcse-lm
-fhoist-adjacent-loads
-finline-functions
-finline-small-functions
-findirect-inlining
-fipa-bit-cp  -fipa-cp  -fipa-icf
-fipa-ra  -fipa-sra  -fipa-vrp
-fisolate-erroneous-paths-dereference
-flra-remat
-foptimize-sibling-calls
-foptimize-strlen
-fpartial-inlining
-fpeephole2
-freorder-blocks-algorithm=stc
-freorder-blocks-and-partition  -freorder-functions
-frerun-cse-after-loop
-fschedule-insns  -fschedule-insns2
-fsched-interblock  -fsched-spec
-fstore-merging
-fstrict-aliasing
-fthread-jumps
-ftree-builtin-call-dce
-ftree-loop-vectorize
-ftree-pre
-ftree-slp-vectorize
-ftree-switch-conversion  -ftree-tail-merge
-ftree-vrp
-fvect-cost-model=very-cheap

-O3

Mümkün olan en yüksek optimizasyon seviyesidir. Ancak bu en efektif çözümü sunduğu anlamına gelmemektedir. Derleme süresini ve RAM kullanımını artırabilir. Kaynak kullanımı artırıldığı için bazı durumlarda sistemin yavaşlamasına bile sebep olabilir. Kullanılan 3th party kütüphaneler eğer -O3 ile oluşturulmamışsa derleme esnasında problemlere yol açabilir.

-O3 ile birlikte otomatik olarak aktif hale gelen flag’ler:

-fgcse-after-reload
-fipa-cp-clone
-floop-interchange
-floop-unroll-and-jam
-fpeel-loops
-fpredictive-commoning
-fsplit-loops
-fsplit-paths
-ftree-loop-distribution
-ftree-partial-pre
-funswitch-loops
-fvect-cost-model=dynamic
-fversion-loops-for-strides

-Os

Kod boyutu optimizasyonu için kullanılır. -O2 optimizasyonunda açılan flag’lerden aşağıda yer alan flag’leri çıkartarak daha az hafıza kullanımını hedefler. Düşük hafızalar cihazlarda çalışıyorken tercih edilebilir.

-Os ile birlikte -O2’den çıkartılan flag’ler:

-falign-functions  
-falign-jumps
-falign-labels  
-falign-loops
-fprefetch-loop-arrays  
-freorder-blocks-algorithm=stc

-Og

Genel kullanım olarak debugging optimizasyonu olarak düşünülebilir. -O0’da yapılan debugging işlemini gerçekleştirirken minimum seviyede optimizasyon yaparak daha sağlıklı bir debug işlemi sunar. -O1 optimizasyonunda açılan flag’lerden aşağıda yer alan flag’leri çıkartarak daha güvenli bir debug işlemi hedefler.

-fbranch-count-reg  
-fdelayed-branch
-fdse  
-fif-conversion  
-fif-conversion2
-finline-functions-called-once
-fmove-loop-invariants  
-fmove-loop-stores  
-fssa-phiopt
-ftree-bit-ccp  
-ftree-dse  
-ftree-pta  
-ftree-sra

-Oz

Optimizasyon olarak hız yerine boyutu önemseyen bir işlem gerçekleştirir. Bu işlemi yaparken daha az boyut kullanabileceğini düşündüğü instruction’ları kullanmaya çalışır. Genel yapı olarak -Os ile benzerlik gösterir. Bu işlemleri yaparken -O2 optimizasyonundaki bir çoğu flag’i de aktif eder.

-Ofast

-fsemantic-interposition flag’ini kapattıktan sonra -O3 içerisindeki tüm flag’lerini aktif ederek standarta uyumlu olmayan programların da kullanılmasına olanak tanır. (Tüm programlar için geçerli değildir.)

Bu işlemi yaparken C++ için aşağıdaki flag’leri de ayrıca aktif hale getirir:

-ffast-math 
-fallow-store-data-races

Compiler üzerinde en temel hatlarıyla gerçekleştirebileceğiniz optimizasyon işlemleri içerilerinde yukarıdaki bilgileri barındırmaktadır. Bu işlemler compile-time’a etki eden optimizasyon işlemleridir. İlerleyen yazılarda Linking-time’a etki edebilecek Link Time Optimizasyon (LTO) konusu için de bir yazı hazırlamayı planlıyorum.

Kaynaklar:

Author

Genel dünya problemleri ile çok ilgili olmasa da teknolojik gelişmeleri yakından takip eden, sistemleri geliştirmek için çalışmalar yapan, bolca kod yazmaya çalışan ve öğrendiklerini paylaşmaya çalışan birisi.

Write A Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.