01 Mayıs 2009 Cuma

Programınız için performans ipuçları.(x86)

Genel amaçlı üretilmiş mimariler üzerinde sinyal işleme, görüntü işleme gibi ağır matematiksel işlemler gerektiren uygulamalar yapıyorsanız optimizasyon çok önemli bir hale gelir.

Bilgisayar tasarımı çalışırken bir zamanlar Türkiye Görüntü İşleme mail grubuna gönderilen bir yazı aklıma geldi. Faydalı bir yazı olduğunu düşündüm ve blogumda paylaşmak istedim. Yazı 17 Şubat 2008 tarihinde Mustafa Sakar tarafından AMD x86 Code Optimization Guide tan yararlanılarak yazılmış.

Özeti biraz daha özetleyip bilgimiz olan yerlere burnumuzu sokarsak ;)

1- 32-bit data tiplerini kullanın. (Neden çünkü mimari bunun üzerine. Bütün aritmatik işlem birimleri 32 bit için design edilmiş. Daha büyük veri tipleri bölünüp yapılır. Küçük olanlarda 32 bitlik registerlara taşınır işaretli ise işaret genişletilir ekstra işlemler...)

2- Integer işlemlerinin işaretine önceden karar verin.
Bölüm ve kalan hesaplarken, döngü sayaçları, array indexleri
için unsigned tipler, Integer-to-float dönüşümleri için signed tipler
kullanın.

Kötü örnek:
double x;        // MOV [tmep+4],0
unsigned int i; // MOV EAX, i
// MOV [temp], EAX
x = i; // FILD QWORD PTR [temp]
// FSTP QWORD PTR [x}
İyi örnek:
double x;        // FILD DWORD PTR [i]
int i; // FSTP QWORD PTR [x]
x = i;
3- Bölme işlemlerini işaretsiz tiplerle yapmak daha hızlıdır.
Kötü örnek:
int i;
i = i / 4; // MOV EAX,i
// CDQ
// AND EDX,3
// ADD EAX, EDX
// SAR EAX, 2
// MOV i, EAX
İyi Örnek:
unsigned i;
i = i / 4; // SHR i,2
4- Pointer-style kod yerine Array-style kod kullan. //Bu çok önemli..
Kötü örnek:
typedef struct {
float x,y,z,w;
} VERTEX;
typedef struct {
float m[4][4];
} MATRIX;

void XForm (float *res, const float *v, const float *m, int
numverts) {
float dp;
int i;
const VERTEX* vv = (VERTEX *)v;
for (i = 0; i < dp =" vv-">x * *m++;
dp += vv->y * *m++;
dp += vv->z * *m++;
dp += vv->w * *m++;
*res++ = dp; /* write transformed x */
dp = vv->x * *m++;
dp += vv->y * *m++;
dp += vv->z * *m++;
dp += vv->w * *m++;
*res++ = dp; /* write transformed y */
dp = vv->x * *m++;
dp += vv->y * *m++;
dp += vv->z * *m++;
dp += vv->w * *m++;
*res++ = dp; /* write transformed z */
dp = vv->x * *m++;
dp += vv->y * *m++;
dp += vv->z * *m++;
dp += vv->w * *m++;
*res++ = dp; /* write transformed w */
++vv; /* next input vertex */
m -= 16; /* reset to start of transform matrix */
}
}

iyi Örnek:
typedef struct {
float x,y,z,w;
} VERTEX;
typedef struct {
float m[4][4];
} MATRIX;

void XForm (float *res, const float *v, const float *m, int
numverts) {
int i;
const VERTEX* vv = (VERTEX *)v;
const MATRIX* mm = (MATRIX *)m;
VERTEX* rr = (VERTEX *)res;
for (i = 0; i <>x = vv->x*mm->m[0][0] + vv->y*mm->m[0][1] +
vv->z*<div id=":1l" class="ii gt"><wbr>mm->m[0][2] + vv->w*mm->m[0][3];
rr->y = vv->x*mm->m[1][0] + vv->y*mm->m[1][1] +
vv->z*<wbr>mm->m[1][2] + vv->w*mm->m[1][3];
rr->z = vv->x*mm->m[2][0] + vv->y*mm->m[2][1] +
vv->z*<wbr>mm->m[2][2] + vv->w*mm->m[2][3];
rr->w = vv->x*mm->m[3][0] + vv->y*mm->m[3][1] +
vv->z*<wbr>mm->m[3][2] + vv->w*mm->m[3][3];
}
}
5- Kısa donguleri tamamen kaldırmalısınız.
Kötü örnek:
// 3D-transform: multiply vector V by 4x4 transform matrix M
for (i=0; i<4; i++) {
r[i] = 0;
for (j=0; j<4; j++) {
r[i] += M[j][i]*V[j];
}
}


İyi Örnek:
// 3D-transform: multiply vector V by 4x4 transform matrix M
r[0] = M[0][0]*V[0] + M[1][0]*V[1] + M[2][0]*V[2] +
M[3][0]*V[3];
r[1] = M[0][1]*V[0] + M[1][1]*V[1] + M[2][1]*V[2] +
M[3][1]*V[3];
r[2] = M[0][2]*V[0] + M[1][2]*V[1] + M[2][2]*V[2] +
M[3][2]*V[3];
r[3] = M[0][3]*V[0] + M[1][3]*V[1] + M[2][3]*V[2] +
M[3][3]*v[3];

6- Gereksiz Store-to-Load hesaplamalardan kacınmalısınız.

Kötü Örnek:
for (k = 1; k < VECLEN; k++) {
x[k] = x[k-1] + y[k]; //Buralar facia durmadan memory e başvur. registera load et
//sonucu geri registerdan memory'e store et..

}
for (k = 1; k < VECLEN; k++) {
x[k] = z[k] * (y[k] - x[k-1]);
}

İyi örnek:
double x[VECLEN], y[VECLEN], z[VECLEN];
unsigned int k;
double t;
t = x[0];

for (k = 1; k < VECLEN; k++) {
t = t + y[k];
x[k] = t;
}
t = x[0];
for (k = 1; k < VECLEN; k++) {
t = z[k] * (y[k] - t);
x[k] = t;
}
7 - Çarpma işlemi bölmeden hızlıdır.
Kötü örnek:
double a,b,c,e,f;
e = a/c;
f = b/c;

İyi örnek:
double a,b,c,e,f,t;
t = 1/c;
e = a*t
f = b*t;
Kötü örnek:
int i,j,k,m;
m = i / j / k;
İyi örnek:
int i,j,k,l;
m = i / (j * k);
8 - Hızlı Floating-Point-to-Integer cevrimi kullanın.
Yavaş Örnek:
double x;
int i;
i = x;

Hızlı Örnek:
#define DOUBLE2INT(i,d) \
{double t = ((d)+6755399441055744.0); i=*((int *)(&t));}

double x;
int i;

DOUBLE2INT(i,x);

***Bazı maddeleri atladım. En önemli gördüklerimi seçmek istedim.
Görüntü işleme ile uğraşıyor performans sıkıntısı yaşıyorsanız hem de çift çekirdekli işlemciniz varsa ilk işiniz bazı işleri paralel yaptırmak olsun. Bluekid abimize link verelim.
OpenMP genel. OpenMP uygulama.

İmkanınız varsa güncel compiler lar kullanın. Yeni compilerla yeni donanımlar için en iyi optimizasyon seçenekleri sağlarlar. Performans bakımından aynı mfc uygulamasının MS un VC++ 9 ile derlenmesi ile VC++ 6 ile derlenmesi arasında inanılmaz farklar gözlenmiştir.

$$$* Ayrıca intel işlemci kullanıyorsanız intelin kendi compiler ı için vaatleri büyük. (Denenmemiştir.)

25 Nisan 2009 Cumartesi

minix3 macerası - 2 (kurulum)

Minix3 için gerekli sistem gereksinimleri şöyle.




  • 386, 486, or Pentium CPU.
  • 16 veya 8 MB ram.
  • Kernel için 50 mB. CD deki diğer paketlerin hepsini kuracaksanın 600 mB harddisk alanı.
  • Boş bir CD iso yun yazmak için. Flashtan boot edebilen bir makinanız varsa flash diskten de kurulum yapabilirsiniz(Ben CD den yaptım.)
VMware, VirtualPC gibi simulatörler üzerinede kurulum yapılabiliyor ama biliyorsunuz bizi bozar onlar.

Kurulum Adımları:

  • Maceraya 00.40 civarında başladım. Minix3 ün resmi download adresinden IDE-3.1.2a.zip (298 MB) zip dosyasını indirdim. Bu dosya indiriledururken içerisinde kurulumla alakalı bilgiler içeren pdf'i okumakta yarar var.
  • Belgede kurulum sırasında ethernet kartının chip seti ile alakalı bilgiler sorulacağı yazıyor bu nedenle ethernet kartımın modelini SURECOM EP-320 X-V/VI 32 Bit olarak not ediyorum bi kenara. (Kartınızın modelini bilmiyorsanız belirtmeden de geçebiliyorsunuz. )
  • Bu sırada iso muş inmiş. Sıkıştırılmış olduğundan windows ortamındaki favori open source zip açıcımız 7zip ile bir güzel açıyoruz.
  • Açılan dosyayı windows ortamının vazgeçilmez cd yazma programlarından ImgBurn programı(2 mb lık efsane) ile cd ye yazıyoruz. 2$ bağışta bulunulabilir ImgBurn un sitesine girmişken ;)
  • Sonra cd mizi sisteme kuracağımız makinaya takıyoruz. Bios tan cd den boot etmesi için ayarı yapıyoruz. (Saat ~02.00)
  • Ben P2 400, 128 MB makina üzerine üzerine kurulum yaptım. Hardiskte yedeklemem gereken hiç bir şey olmadığından kurulumun otomatik olarak yaptığı partition yapısını kullandım. Bu nedenle partition lama işlemlerini çok iyi bilemeyeceğim. Siz eğer sistemininiz yanına kurulum yapmak isterseniz bu dökümanı okuyun derim.
  • Kurulum başladığında önce bir açıklama geliyor. Sonra klavye tipini soruyor. Enter a basarak default değeri seçebiliyorsunuz. (ing klavye diziliminde kullanacağız.) Ethernet kartınızın chipseti hakkında bilgi istiyor. 0 seçerek direk geçebilirsiniz.(no networking) Veya bunlar dışında (7) diyip daha sonra configure etmek için bırakabilirsiniz. Ben burada kendi ethernet kartı bilgilerimi göremediğime şaşırmadım çünkü windows bile tanımıyor. Her kurulumda driver arıyorum. Realtek vs çok kullanılan chipsetler mevcut.
  • Nasıl bir kurulum yapmak istediğimizi soruyor. Minimal kurulum veya tam kurulum yapabiliriz. Ben tam kurulum için "F" seçeneğini kullandım.
  • Partitioning işlemlerine sıra geldi ben direk tek disk üzerine tek partionda kurulum yapmak istediğimden default seçeneklerle ilerliyorum. disk number "0" enter region number "0" enter.
  • home klasoru için kaç mb yer ayırmak istediğimizi soruyor. 200 mb değer verdim.
  • Kilobyte cinsinden blocksize ı soruyor. Default olan 4Kb ı seçtim. Daha kısıtlı kaynaklar için değişik kb lar seçilebiliyor.
  • Daha sonra disk yüzeyinde bad sector taramasına başlıyor. İkinci adımda dayanamadım(epey uzun sürecekti. ilerleme grafiğine bakılırsa) ctrl+c ile işlem tamamlanmadan devam ettim.
  • Tüm işlemler 10 dk civarı sürdü. Ve sistemimiz hazır oldu. shutdown diyerek sistemden logout oluyoruz.(çünkü live cd üzerinden çalışıyor) ve boot komutu ile sistemi yüklediğimiz yerden boot ediyoruz. Komut "boot dXp0" şeklinde. Burada X biosta görülen sürücü numarası.(Kaçıncı disk olduğu.) p den sonrasıda partition. Bizim kurulumumuz için komut "boot d0p0" şeklinde...
  • shutdowndan sonra konsole tekrar düşüyoruz yukarıdaki şekilde boot komutunu verdiğimizde login: root, pass: ""(hiç bir şey yazmadan enter) şeklinde login oluyoruz. Sistemi unix komutları ile gezebiliriz. Bu esnada. Eğer paket kurmak istersek packman isminde paket yönetici var. packman komutu ile başlatabiliyoruz.
  • packman ile internetten veya cd den paket kurulumu yapabiliriz. cd cd sürücüde iken packman komurunu verdiğimizde cd deki paketleri tarıyor 1 seçeneği ile tüm paketleri kurabiliriz. 2 ile tüm paketler + source kodlarını kurabiliriz. 3 ile istediğimiz paketi seçebiliriz. 4 seçeneği ile ise packmanden çıkabiliyoruz.
  • Benim ethernet kartım tanınmadığı için kurulum cdsi ile gelen paketleri kurdum. Bu aşama biraz uzun sürebiliyor. (İlk aşamada sadece binary leri kurmanızı tavsiye ederim.) 30-45 dakika civarı sürebilir. Kurulum sırasında sistem tepkisiz görünebilir hemen resetlemeyin.(nede olsa yüksek kararlı sistem kullanıyoruz ;) ) Kurulum tamamlansın. Devamı inşallah sonraki yazıya.
*Biraz aksilikler çıktı ama sabah 06.00 civarında xwindowu gördüm. Yazının devamı gelecek. It's time to study. ;)

minix3 macerası - 1


Uzun bir zamandır görüntü işleme uygulamaları geliştirip çalıştırabileceğim hızlı bir şekilde açılıp kapanabilen ama üzerinde arayüz uygulayabileceğim gömülü bir dağıtım bakıyordum.




Kendisinden çok şey öğrendiğimiz Bluekid abimiz sağolsun minix3 ü önerdi. Minix3 tam aradığım özelliklere sahip ayrıca üzerinde FLTK çalışabiliyor. ;)




Minix3 ün sitesinde sistemin hedef alanları olarak şunlar gösteriliyor.



  • Yüksek derecede kararlılık (reliability) istenen uygulamalarda.
  • Tek-chip, küçük ram e sahip, düşük güç tüketen cihazlar vs.
  • Embedded sistemler. (camera, cep telefonu vs.).
  • GPL lisansının çok kısıtlayıcı olduğu uygulamalar.(minix3 BSD lisansına sahiptir.)
  • Eğitim.(Üniversitelerde Operating System dersleri için.)
Linuxun gelişimini takip edememiş birisi olarak hep linux kerneli çok karmaşık, linux configurasyonu zor gelir(ya da gözümde büyütüyorum.) Uzun zamandır değişik linux dağıtımlar kullansamda alt seviyelere hiç inemedim.




Minix3 dağıtımının bir güzel özelliği de bu. Henüz bakmadım ama ~5000 satırlık bir kernel kodu varmış. Üzerinde çalıştırılabilinecek kütüphaneler ise bir hayli fazla. Bknz.




Buradan screenshot lara göz atabilirsiniz.
Bir ayda yaklaşık 12000 kişi iso dosyasını siteden indirip kurulum yapıyormuş.Buranın yalancısıyım.




Ben de evdeki emektar makinayı(Intel P2 400,256 Mb Ram) bu sistemden mahrum bırakmak istemedim. Bir gece uğraşarak xwindow u görmeyi başardım. Gerçekten sisteme çok içim ısındığını söylemeliyim. Keşke derslerden projelerden biraz daha vakit olsada doya doya kurcalayabilsem. Uzun bir süre makinada kalacak gibi görülüyor. Üzerinde önce fltk yı çalıştırıp basit uygulamalar yapmak sonrada opencv çalıştırmak gibi düşüncelerim var.




* Yalnız sistemde floating point donanımsal olarak desteklenmiyormuş. Bu iş nasıl etkiler bilemiyorum. Beraber görelim..

13 Mart 2009 Cuma

x86 --> MIPS Cross Derleme

  • MIPS RISC yapısına sahip bir mikroişlemci mimarisidir.Karşılaştırmak ne kadar uygun olur bilmiyorum ama komut seti Intel x86 komut setine göre oldukça temiz ve basit. Bu tasarım avantajından dolayı üniversitelerdeki bilgisayar mimarisi derslerinde genellikle MIPS mimarisi okutulur.(vikipedi). Benim yeni okulumda da öyle..

  • Intel x86 işlemcili makinam üzerinde bir C kodunu derleyip MIPS assembly si elde etmem gerekiyordu. Gcc ile target mimari belirtilebildiğini biliyordum, deneyince bu kadar kolay olmadığını gördüm. Bu işlemi yapabilmek için gcc nin kaynak kodunu tekrardan özel parametrelerle derlemem gerekiyormuş. (ubuntu'da başarılı olamadım...)

  • Daha sonra aramalarıma devam ederken princeton uni. den "lcc" isimli bir cross compiler buldum. (http://www.cs.princeton.edu/software/lcc/) Windows ve linux versiyonları mevcut. Ben windows versiyonunu kullandım. Gayet kullanışlı. MIPSR3000 için little endian ve big endian derleme yapabiliyor. (ALPHA, SPARC ve Intel x86 için de yapabiliyormuş.)

  • Microsoft VC++ 4 embedded da Microsoftun artık ücretsiz olarak dağıttığı çok değişik mimariler için derleme yapabileceğimiz bir araç. MIPS asm side üretiyor.

10 Temmuz 2008 Perşembe

Dalgacık.

  • ...Foton, kütlesi 0 olan; saniyede 300 000 km hızla giden en küçük dalga/parçacık tır. Gerçek cisim tanecikleri de ışık gibi aynı temele dayanıyor. Gezegenleri, yıldızları ve galaksileri oluşturan madde, enerji dalgalarından üretilen taneciklerdir.
  • Durağan görünen bedenimizin temelinde, sayısız foton süper hızla akış halindedir. Bedenimiz ışık hızında gerçekleşen bir dalga akışıdır.
  • Vücudumuz kuantum dalgalarından örülen taneciklerden, onlardan örülü atomlardan, onlardan örülü moleküllerden veonlardan örülü hücrelerden yapılmıştır. Işık hızında fotondan örülen tanecik yavaşlar; onlardan örülen atom daha da yavaşlar. Böylece örgü elementleri kayalara, kıtalara, gezegenlere, galaksilere ulaşır.
  • Yerinde duruyor gibi görülen her madde, bedenin derinlerinde baş döndürücü titreşimleri, fırtınaları, uçuşmaları gizlemektedir.
  • Maddenin aslı, süper hızlı enerji dalgalarıdır. Madde aslında enerjidir; ama, ilginçtir ki enerjinin maddi vücudu yoktur. Sobanızda yaktığınız odunlar kül olup havaya uçar. Kütlesi enerjiye yani evinizdeki maddenin atomlarında yaşanan titreşimine/ısıya dönüşür.
  • Odun yanarak yok olur ; karşılığında sadece çevresindeki maddeleri titreştirir.
  • ... Evrenin tüm enerjisi vücutsuz bir zerreye sıkışabilir.


Dr. Muhammed Bozdağ. 2005