Özeti biraz daha özetleyip bilgimiz olan yerlere burnumuzu sokarsak ;)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.)
4 yorum - yorum yaz:
Görüntü İşleme ile ilgili bir mail grubu olduğunu bilmiyordum, öğrendiğim iyi oldu :)
Bu sıralar pek aktif değil ama.. :(
E-posta grubu uzun zamandır aktif değil gibi görünüyor. Sağlık olsun diyelim :)
kod optimizasyonu için gnu derleyicilieri kullanırken -O3 parametresi kullanılabilir ayrıca.
Yorum Gönder