UYBHM Yaz Çalıştayı 15 Haziran 2011 Derleme Make Hata Ayıklama Cem Ahmet MERCAN
Neler Anlatılacak? ( Compiling ) Derleme Make / Makefile ( Debug ) Hata Ayıklama
UYBHM Yaz Çalıştayı 15 Haziran 2011 Derleme Cem Ahmet MERCAN
Intel/GNU Yazılım Geliştirme Araçları Intel Derleyiciler: GNU Derleyiciler: Intel C Compiler (icc) gcc Intel C++ Compiler (icpc) g++ Intel Fortran Compiler (ifort) gfortran Intel Debugger (idb) gdb Intel Performans Kütüphaneleri: Intel Math Kernel Library Intel Threading Building Blocks Intel Performance Primitive Muadilleri: Blas,Lapack,scalapack
( II ) Intel/GNU Yazılım Geliştirme Araç. Intel Profil çıkarma ve Analiz Araçları: Intel Vtune Performance Analyzer Intel Thread Checker Intel Cluster Tools : Intel MPI Intel Trace Analyzer and Collector Cluster OpenMP for Intel Compilers Muadilleri: gprof,valgrind Muadilleri: mpich
İntel Derleyici ve MPI # for using intel compilers and mpi libs export INTEL_LICENSE_FILE=/RS/progs/intel/licenses:/opt/intel/licenses. /RS/progs/intel/Compiler/11.1/069/bin/iccvars.sh intel64. /RS/progs/intel/Compiler/11.1/069/bin/ifortvars.sh intel64. /RS/progs/intel/impi/3.1/bin64/mpivars.sh # Intel Trace Analyzer and Collector. /RS/progs/intel/itac/7.1/bin/itacvars.sh # Intel Thread Checker. /RS/progs/intel/Tcheck/bin/Tvars.sh # Intel Vtune Performance Analyzer. /opt/intel/vtune/bin/vtunevars.sh
merhaba.c: Merhaba Dünya! #include <stdio.h> int main() { printf("merhaba Dunya!\n"); exit(0); }
Basit Derleme İntel: C: icc merhaba.c -o merhaba.x C++: icpc merhaba.cpp -o merhaba.x Fort: ifort merhaba.f90 -o merhaba.x GNU: C: gcc merhaba.c -o merhaba.x C++: g++ merhaba.cpp -o merhaba.x Fort: gfortran merhaba.f90 -o merhaba.x g77 merhaba.f77 -o merhaba.x
Koddan Çalışan Program Oluşturma #include<stdio.h> () main int { printf( Merhaba ); } Derleme Derlenmiş Kod 1 #include<stdio.h> (...,* int printf(char {... } Derleme Derlenmiş Kod 2 Link Çalışan Uygulama
İki Adımda Derleme İntel: icc -c merhaba.c icc merhaba.o -o merhaba.x Derleme Aşaması Link Aşaması GNU: gcc -c merhaba.c gcc merhaba.o -o merhaba.x
Koddan Çalışan Program Oluşturma DEĞİŞEN KISIM! #include<stdio.h> () main int { printf( Merhaba ); } #include<stdio.h> (...,* int printf(char {... } Derleme Derleme Derlenmiş Kod 1 Derlenmiş Derlemeye Gerek Yok! Kod 2 Link Çalışan Uygulama
Birden Çok Dosyalı Kod Derleme Tek seferde: icc dosya1.c dosya2.c -o uygulama.x Her dosya ayrı: icc -c dosya1.c icc -c dosya2.c icc dosya1.o dosya2.o -o uygulama.x
( Optimization ) En iyileme -O[n] parametresi ile verilir: O0 optimizasyon kapalı O1 Uygulamanın boyutunu büyütmeden optimizasyon yapar. Döngü ağırlıklı kodlar için uygun değildir. O2 Standart optimizasyon, normalde zaten yapılan bu. Genelde en hızlı kodu bu üretir. O3 Standart optimizasyona ilaveten bazı ilave abartılı optimizasyonlar yapar. Özellikle büyük veri dizileri üzerinde çalışan çokca döngü içeren kodlar için uygundur (YBH gibi). Os Optimizasyonun kodu büyütmesini engeller.
En iyileme (Optimization): FAST *** Sadece İntel Derleyicilerde -fast parametresi ile:-o3 -ipo -static -xhost -no-prec-div O3 Abartılı optimizasyon yap ipo birden fazla dosyaya bölünmüş kısımları da gözeterek optimizasyon yapar. static shared kütüphaneleri kullanmaz. xhost CPU'a özel kod üretir. Bazı cpu'lar için bu desteklenmediğinden bu eklenmez. no-prec-div Bölmede hassasiyeti azaltıp hızlan.
(Debuging ) Hata Ayıklama -g ile hata ayıklama bilgisi programa eklenir. Ayrıca optimizasyon kapatılır ( -O0 ). icc -g merhaba.c -o merhaba.x gcc -g merhaba.c -o merhaba.x
Parametre Sırası Sonraki parametre öncekinin etkisini kaldırır: icc -fast -g dersek: icc -ipo -static -xhost -g -O0 demiş oluruz. icc -g -O2 -g ile kapatılan optimizasyon açılır.
İşlemciye özel optimizasyon *** Diğer işlemciler de çalıştırabilir. Gcc/icc Hangi cpu için: -mcpu=pentium -mcpu=pentiumpro -mcpu=pentium4 -mcpu=itanium Intel Pentium Intel Pentium Pro Intel Pentium 4 SSE3 Itanium -mcpu=itanium2 Itanium 2
İşlemciye özel optimizasyon (intel) -x<tür> Diğer işlemciler de hatalı çalışır / reddeder Host, AVX, SSE4.2, SSE3_ATOM, SSE4.1, SSSE3, SSE3, SSE2, S, T, P, O, B, N, W, K -ax<tür> Optimize kodun normal versiyonunu da tutar SSE4.2, SSE3_ATOM, SSE4.1, SSSE3, SSE3, SSE2,S, T, P, O, B, N, W, K Örnek: icc -axsse4.1,ssse3 merhaba.c
Uyarılar -Wall Tüm uyarıları göster -w Tüm uyarıları kapar -Wcheck Kodu derlerken ilave kontroller yap -Weffc++ Effective C++ programming kitabındaki önerilere göre kontrol et. -pedantic ISO standartına uymayanlar için uyar
( intel ) Otomatik Paralelleştirme -parallel ile SMP makineler için paralelleştirme yapılır: icc -parallel merhaba.c -o merhaba.x OMP_NUM_THREADS değişkeni ile kaç thread ile çalıştırılacağı kontrol edilir: export OMP_NUM_THREADS=4./merhaba.x
( intel ) Otomatik Paralelleştirme Fortran 'da sadece DO döngüleri paralelleştirilir. C/C++ 'da sadece for döngüleri paralelleştirilir. Pointer aritmetiği içeren döngüler paralelleştirilmez! Diğer döngü yapıları (while vb.) paralelleştirilmez! Diğer döngü olmayan kodlar da paralelleştirilmez! OpenMP ile paralelleştirilir, SMP şart!
Ne?
Matriks Çarpımı #include<stdio.h> #define SIZE 1000 double a[size][size]={0}; double b[size][size]={0}; double c[size][size]={0}; int main(int argc, char ** argv) { long i,j,k; double top=0; printf ("Bir matrisin boyutu= %.2lf MB\n",SIZE*SIZE*sizeof(double)/1048576.0); for (i=0;i<size;i++){ for (j=0;j<size;j++){ a[i][j]=i-j; b[i][j]=j-i; c[i][j]=0; }} for (i = 0; i < SIZE; i++){ for (j = 0; j < SIZE; j++){ for (k = 0; k < SIZE; k++){ c[i][j] += a[i][k] * b[k][j]; }}} for (i=0;i<size;i++){ for (j=0;j<size;j++){ top+=c[i][j]; }} printf ("C toplamı= %.2lf\n",top); }
Basit Matris Çarpımı - C Tek Dosya, Sadece Main Fonksiyonu Derleyici Parametreleri Gcc o3 static Gcc o2 Gcc o3 Gcc g Gcc nopar * Autopar (2 cpu) * ipo static o2 * ipo static o3 * o2 * fast o2 * fast * o3 g * nopar 119 263 153 263 263 152 151 263 4205 4195 4129 * Farklı Sonuç D: 260416656250007040.00 F: 260416656250009984.00 41 Kat Hızlanma 6290 6249 6198 0 1000 2000 3000 4000 5000 6000 7000 Geçen Süre (Saniye olarak)
Matris Çarpımı - Cij = Aik * Bkj 350 300 İcc 11.1 fast Gcc4.1 O3 İcc 11.1 g Gcc4.1 g Döngü Sıralamasının Etkisi 288 313 250 221 239 200 Saniye 150 100 86 110 94 124 50 22 60 61 42 0 i k j k i j j i k i j k j k i k j i
Bağımlılığı Fazla C++ Kodu Birçok dosyada, pek çok fonksiyon mevcut Gcc o2 Gcc o3 Gcc g Gcc nopar 12716 12486 18767 18718 Derleyici Parametreleri o2 inline 16344 ipo static o2 16492 ipo static o3 16795 o2 16543 fast o2 16655 fast 16785 o3 16490 g 21686 nopar 16656 0 5000 10000 15000 20000 25000 Geçen Süre (Saniye olarak)
( intel ) Raporlar -vec-report{0 1 2 3 4 5} SSE3 vektörleştirme bilgisi -opt-report{0 1 2 3} Optimizasyon bilgisi -par-report{0 1 2 3} Otomatik paralelleştirme bilgisi 0 bilgi verme - 1 default - 2-3 en fazla bilgi icc -vec-report3 -fast matmul.c -o matmul.x
Vec-report icc -vec-report3 -fast matmul.c -o matmul.x matmul.c(13): (col. 2) remark: loop was not vectorized: not inner loop. matmul.c(15): (col. 3) remark: loop was not vectorized: vectorization possible but seems inefficient. matmul.c(22): (col. 2) remark: loop was not vectorized: not inner loop. matmul.c(22): (col. 2) remark: loop was not vectorized: not inner loop. matmul.c(22): (col. 2) remark: loop was not vectorized: not inner loop. matmul.c(22): (col. 2) remark: loop was not vectorized: not inner loop. matmul.c(26): (col. 4) remark: loop was not vectorized: not inner loop. matmul.c(24): (col. 3) remark: PERMUTED LOOP WAS VECTORIZED. matmul.c(32): (col. 2) remark: LOOP WAS VECTORIZED.
UYBHM Yaz Çalıştayı 15 Haziran 2011 Make Cem Ahmet MERCAN
Birine bağımlı 30 kod dosyası varsa? DEĞİŞEN KISIM! #include<stdio.h> () main int { printf( Merhaba ); } #include<stdio.h> (...,* int printf(char {... } Derleme Derleme Derlenmiş Kod 1 Derlenmiş Derlemeye Gerek Yok! Kod 2 Link Çalışan Uygulama
Makefile <hedef> : <bağımlılık> <bağımlılık>... (tab)<yapılacak işlem> (tab)<yapılacak işlem>...
Makefile merhaba.x : merhaba.c icc -fast merhaba.c -o merhaba.x uygulama.x : dosya1.c dosya2.c dosya1.h icc -g dosya1.c dosya2.c -o uygulama.x
Make $ make merhaba.x icc -fast merhaba.c -o merhaba.x $ make uygulama.x $ make icc -g dosya1.c dosya2.c -o uygulama.x icc -fast merhaba.c -o merhaba.x
( dosya Makefile (birden fazla uygulama.x : dosya1.o dosya2.o genel.h icc dosya1.o dosya2.o -o uygulama.x dosya1.o: dosya1.c dosya1.h genel.h icc -c dosya1.c dosya2.o: dosya2.c dosya2.h genel.h icc -c dosya2.c
( dosya Make (birden fazla $ make icc -c dosya1.c icc -c dosya2.c icc dosya1.o dosya2.o -o uygulama.x $ make make: `uygulama.x' is up to date. $ touch dosya1.c ; make icc -c dosya1.c icc dosya1.o dosya2.o -o uygulama.x
( DEĞİŞKENLER ) Makefile CC=icc CFLAGS= -O3 -ipo uygulama.x : dosya1.o dosya2.o genel.h $(CC) $(CFLAGS) dosya1.o dosya2.o -o uygulama.x dosya1.o: dosya1.c dosya1.h genel.h $(CC) $(CFLAGS) -c dosya1.c dosya2.o: dosya2.c dosya2.h genel.h $(CC) $(CFLAGS) -c dosya2.c
( DEĞİŞKENLER ) Makefile CC=gcc CFLAGS= CXX=g++ CXXFLAGS= FC = g77 FFLAGS= CPP= $(CC) -E CPPFLAGS= LD = ld LDFLAGS = LFLAGS = LOADLIBS = MAKE = make MAKEARGS = 'SHELL=/bin/sh' SHELL = /bin/sh ***Ayrıca tüm çevre değişkeleri makefile'a aktarılır.
( DEĞİŞKENLER ) Makefile # = işareti ile atama değişik davranır AA= Nerede BB= $(AA) Burada AA= Hersey # Artik BB = Hersey Burada AA=$(BB) # Hata, makefile sonsuz döngüye girecekti # Olası çözüm := AA= Nerede BB:= $(AA)_Burada AA:=$(BB) # Sorun yok, AA = Nerede_Burada
( PHONY ) Makefile all: uygulama.x merhaba.x clean: rm *.o rm uygulama.x merhaba.x.phony: all clean
( Parametreler ) Make $ make -B icc -c dosya1.c icc -c dosya2.c icc dosya1.o dosya2.o -o uygulama.x $ make -f gcc_ile_derle gcc -c dosya1.c gcc -c dosya2.c gcc dosya1.o dosya2.o -o uygulama.x
Otomatik Değişkenler $@ hedefin adını tutar $* hedef ile bağımlılıkların ortak başlangıç bölümü $^ bağımlılıkların tümünü tutar $< bağımlılıklardan ilkini tutar $? hedeften yeni olan tüm bağımlılıklar
( Değişkenler Makefile (Otomatik CC=icc CFLAGS= -O3 -ipo uygulama.x : dosya1.o dosya2.o $(CC) $(CFLAGS) $^ -o $@ dosya1.o: dosya1.c dosya1.h genel.h $(CC) $(CFLAGS) -c $< dosya2.o: dosya2.c dosya2.h genel.h $(CC) $(CFLAGS) -c $<
( kuralları Makefile (Tür CC=icc CFLAGS= -O3 -ipo % : %.o $(CC) $(CFLAGS) $^ -o $@ %.o: %.c %.h genel.h $(CC) $(CFLAGS) -c $<
( Fonksiyonlar ) Makefile CC=icc CFLAGS= -O3 -ipo ( c.* SOURCES = $(wildcard (( c,%.o,$(sources.% OBJS = $(patsubst ( OBJ )$ : % $(CC) $(CFLAGS) $^ -o $@ %.o: %.c %.h genel.h $(CC) $(CFLAGS) -c $<
UYBHM Yaz Çalıştayı 15 Haziran 2011 Hata Ayıklama Cem Ahmet MERCAN
Hata Ayıklama (Debuging) -g ile: hata ayıklama bilgisi programa eklenir. Ayrıca optimizasyon kapatılır ( -O0 ). icc -g merhaba.c -o merhaba.x gcc -g merhaba.c -o merhaba.x
(Debuging ) Hata Ayıklama gnu debugger modunda açılış: $ idb -gdb./merhaba.x (idb) run $ idb -gdb (idb) file./merhaba.x (idb) run
(Debuging ) Hata Ayıklama Çalışan uygulamaya bağlantı: $./merhaba.x & [1] 3742 $ idb -gdb./merhaba.x -pid 3742 (idb) $./merhaba.x & [1] 3742 $ idb -gdb (idb) file./merhaba.x (idb) attach 3742
(RUN ) Hata Ayıklama $ idb -gdb./merhaba.x (idb) run (idb) run parametreler (idb) run parametreler <girdi-dosyası (idb) run parametreler >cikti-dosyası (idb) r
$ idb -gdb./a.out (idb) run ^C Hata Ayıklama (Durma) Program received signal SIGINT, Interrupt. 0x00001d75 in matrixmultiply (C=0xf624000, A=0x200000, B=0x7c12000, awcw=4000, ahbw=4000, bhch=4000) at matrixoperations.c:33 33 C[((h*awcw)+w)]+=A[((k*awcw)+w)]*B[((h*ahbw)+k)]; (idb) run Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_PROTECTION_FAILURE at address: 0xbf3072f8 0x00001f53 in main () at merhaba.c:20 20 fillwith(a, asize, 1.2);
(Durma ) Hata Ayıklama $ idb -gdb./merhaba.x (idb) break main (idb) run Breakpoint 1, main (argc=4, argv=0xbffff894) at merhaba.c:8 8 int awcw=4; (idb) run (idb) break main (idb) watch bhch (idb) continue Hardware watchpoint 2: bhch Old value = 0 New value = 8 main (argc=4, argv=0xbffff89c) at merhaba.c:12 ( argc==4 ) 12 if
(idb) help Temel Komutlar (idb) help break (idb) quit (idb) info source (idb) list (idb) list 10,+30 (idb) list 20,45 (idb) list matrixoperations.c:fillwith (idb) list matrixoperations.c:10,20
Break (idb) break main (idb) break 17 (idb) break matrixoperations.c:100 (idb) break matrixoperations.c:fillwith (idb) break (idb) break 100 if awcw>12 (idb) br
( bt ) Backtrace Stack yapısını gösterir, programın nerede durduğunu ve oraya nereden geldiğini görürüz: (gdb) bt #0 fillwith (A=0x100120, asize=4, x=1.2) at matrixoperations.c:6 #1 0x00001f20 in main (argc=4, argv=0xbffff8a4) at merhaba.c:28 (gdb) bt #0 fillwith (A=0x100140, asize=4, x=0) at matrixoperations.c:6 #1 0x00001c9b in makeidentity (B=0x100140, ahbw=2, bhch=2) at matrixoperations.c:18 #2 0x00001f39 in main (argc=4, argv=0xbffff8a4) at merhaba.c:29
(gdb) bt full ( bt ) Backtrace #0 fillwith (A=0x100120, asize=4, x=1.2) at matrixoperations.c:6 s = 214748364 #1 0x00001f20 in main (argc=4, argv=0xbffff8a4) at merhaba.c:28 awcw = 2 ahbw = 2 bhch = 2 asize = 4 bsize = 4 csize = 4 A = (double *) 0x100120 B = (double *) 0x100140 C = (double *) 0x100160
Komutlar Diğer <enter> son girilen komutu tekrar eder (idb) continue bir olay olana kadar çalış (idb) continue n n adet olay olana kadar çalış (idb) next bir sonraki satırı çalıştır,fonksiyonun içine girmez (idb) nexti bir sonraki komutu çalıştır,fonksiyonun içine girmez (idb) next n n adet satırı çalıştır (idb) step bir sonraki satırı çalıştırır, fonksiyonun içine girer (idb) stepi bir sonraki komutu çalıştırır, fonksiyonun içine girer (idb) step n n adet satırı çalıştırır (idb) finish bu stack'e tekrar dönene kadar devam eder (idb) print <değişken> değişkenin değerini yazar (idb) del n breakpoint'i siler
UYBHM Yaz Çalıştayı 15 Haziran 2011 IDE - Eclipse Cem Ahmet MERCAN
UYBHM Yaz Çalıştayı 15 Haziran 2011 Teşekkürler Cem Ahmet MERCAN