Slayt 1 - Indico
Transkript
Slayt 1 - Indico
UYBHM Yaz Çalıştayı 15 Haziran 2011 Derleme – Make – Hata Ayıklama Cem Ahmet MERCAN Neler Anlatılacak? • Derleme (Compiling) • Make / Makefile • Hata Ayıklama (Debug) UYBHM Yaz Çalıştayı 15 Haziran 2011 Derleme Cem Ahmet MERCAN Intel/GNU Yazılım Geliştirme Araçları Intel Derleyiciler: Intel® C Compiler (icc) Intel® C++ Compiler (icpc) Intel® Fortran Compiler (ifort) Intel® Debugger (idb) Intel Performans Kütüphaneleri: Intel® Math Kernel Library Intel® Threading Building Blocks Intel® Performance Primitive GNU Derleyiciler: gcc g++ gfortran gdb Muadilleri: Blas,Lapack,scalapack Intel/GNU Yazılım Geliştirme Araç. (II) Intel Profil çıkarma ve Analiz Araçları: Intel® Vtune™ Performance Analyzer Intel Thread Checker Muadilleri: gprof,valgrind “Intel Cluster Tools”: Intel® MPI Intel® Trace Analyzer and Collector Cluster OpenMP for Intel® Compilers 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 Dünya! merhaba.c: #include <stdio.h> int main() { printf("Merhaba Dunya!\n"); exit(0); } Basit Derleme İntel: C: C++: Fort: GNU: C: C++: Fort: icc merhaba.c -o merhaba.x icpc merhaba.cpp -o merhaba.x ifort merhaba.f90 -o merhaba.x gcc merhaba.c -o merhaba.x g++ merhaba.cpp -o merhaba.x gfortran merhaba.f90 -o merhaba.x g77 merhaba.f77 -o merhaba.x Koddan Çalışan Program Oluşturma #include<stdio.h> int main() { printf(“Merhaba”); } Derleme Derlenmiş Kod 1 Link #include<stdio.h> int printf(char *,...) { .... } Derleme Derlenmiş Kod 2 Çalışan Uygulama İki Adımda Derleme İntel: icc -c merhaba.c icc merhaba.o -o merhaba.x GNU: gcc -c merhaba.c gcc merhaba.o -o merhaba.x Derleme Aşaması Link Aşaması Koddan Çalışan Program Oluşturma DEĞİŞEN KISIM! #include<stdio.h> int main() { printf(“Merhaba”); } Derleme Derlenmiş Kod 1 Link Derlenmiş Derleme Derlemeye GerekKod Yok! 2 #include<stdio.h> int printf(char *,...) { .... } Ç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 En iyileme (Optimization) -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. 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 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 Intel® Pentium® -mcpu=pentiumpro Intel Pentium Pro -mcpu=pentium4 Intel Pentium 4 SSE3 -mcpu=itanium 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 Otomatik Paralelleştirme (intel) -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 Otomatik Paralelleştirme (intel) • 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 Gcc o3 static 4205 Gcc o2 4195 Derleyici Parametreleri Gcc o3 4129 Gcc g 6290 Gcc nopar 6249 * Autopar (2 cpu) 119 * ipo static o2 * Farklı Sonuç D: 260416656250007040.00 F: 260416656250009984.00 263 * ipo static o3 153 * o2 263 * fast o2 263 * fast 152 * o3 151 41 Kat Hızlanma g 6198 * nopar 263 0 1000 2000 3000 4000 Geçen Süre (Saniye olarak) 5000 6000 7000 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 313 288 239 250 221 Saniye 200 150 110 100 86 0 94 61 60 50 124 42 22 ikj kij jik ijk jki kji Bağımlılığı Fazla C++ Kodu Birçok dosyada, pek çok fonksiyon mevcut Gcc o2 12716 Derleyici Parametreleri Gcc o3 12486 Gcc g 18767 Gcc nopar 18718 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 Geçen Süre (Saniye olarak) 20000 25000 Raporlar (intel) -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> int main() { printf(“Merhaba”); } Derleme Derlenmiş Kod 1 Link Derlenmiş Derleme Derlemeye GerekKod Yok! 2 #include<stdio.h> int printf(char *,...) { .... } Ç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 icc -g dosya1.c dosya2.c -o uygulama.x $ make icc -fast merhaba.c -o merhaba.x Makefile (birden fazla dosya) 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 Make (birden fazla dosya) $ 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 Makefile (DEĞİŞKENLER) 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 Makefile (DEĞİŞKENLER) CC=gcc LD = ld CFLAGS= LDFLAGS = CXX=g++ LFLAGS = CXXFLAGS= LOADLIBS = FC = g77 MAKE = make FFLAGS= CPP= $(CC) -E MAKEARGS = 'SHELL=/bin/sh' CPPFLAGS= SHELL = /bin/sh ***Ayrıca tüm çevre değişkeleri makefile'a aktarılır. Makefile (DEĞİŞKENLER) # = 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 Makefile (PHONY) all: uygulama.x merhaba.x clean: rm *.o rm uygulama.x merhaba.x .PHONY: all clean Make (Parametreler) $ 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 Makefile (Otomatik Değişkenler) 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 $< Makefile (Tür kuralları) CC=icc CFLAGS= -O3 -ipo % : %.o $(CC) $(CFLAGS) $^ -o $@ %.o: %.c %.h genel.h $(CC) $(CFLAGS) -c $< Makefile (Fonksiyonlar) CC=icc CFLAGS= -O3 -ipo SOURCES = $(wildcard *.c) OBJS = $(patsubst %.c,%.o,$(SOURCES)) % : $(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 Hata Ayıklama (Debuging) gnu debugger modunda açılış: $ idb -gdb ./merhaba.x (idb) run $ idb -gdb (idb) file ./merhaba.x (idb) run Hata Ayıklama (Debuging) Ç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 Hata Ayıklama (RUN) $ idb -gdb ./merhaba.x (idb) run (idb) run parametreler (idb) run parametreler <girdi-dosyası (idb) run parametreler >cikti-dosyası (idb) r Hata Ayıklama (Durma) $ idb -gdb ./a.out (idb) run ^C 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); Hata Ayıklama (Durma) $ 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 12 if (argc==4) (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 Backtrace (bt) 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 Backtrace (bt) #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 Diğer Komutlar <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> (idb) del n değişkenin değerini yazar 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