7 octombrie 2006 02:34
by
Victor
O surpriză inedită
Nu demult timp lucram la o aplicaţie ce trebuia să transforme în grayscale un obiect de tip Bitmap, cu pixelii reprezentaţi pe 24bpp. Pentru acest lucru foloseam două for-uri pentru accesarea fiecarui pixel. Imaginea mea avea o dimensiune destul de mare (1600x1024).
Acestă transformare o mai implementasem de 2-3 ori cu coeficienţi diferiţi iar acum doream sa încerc un nou set de parametrii. Din lene, am rescris tot codul de mana (trebuia sa deschis un alt proiect, multe linii de cod...incomod). La rulare, surpriză.
Cât este diferenta intre cei doi algoritmi?
public Bitmap Grayscale1(Bitmap srcImg)
{
...
// get source image size
int width = srcImg.Width;
int height = srcImg.Height;
// for each line
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++, src += 3)// for each pixel
{
src[0] = src[1] = src[2] = (byte)( 0.2125 * src[2] + 0.7154 * src[1] + 0.0721 * src[0]);
}
...
}
...
return srcImg;
}
public Bitmap Grayscale2(Bitmap srcImg)
{
...
// for each line
for (int y = 0; y < srcImg.Height; y++)
{
for (int x = 0; x < srcImg.Width; x++, src += 3)// for each pixel
{
src[0] = src[1] = src[2] = (byte)( 0.2125 * src[2] + 0.7154 * src[1] + 0.0721 * src[0]);
}
...
}
...
return srcImg;
}
Răspuns:
Nu întâmplător am pus întrebarea „Cât”. Răspunsul este 1.7 secunde.
Algoritmul Grayscale2 procesa imaginea mult mai greu decât Grayscale1 şi nu îmi explicam de ce din moment ce foloseam aceaşi dimensiune a pozei, aceiaşi coeficienţi, acelaşi număr de înmulţiri. Răspunsul este simplu:
width si height – sunt două variabile declarate local metodei Grayscale1. În momentul în care se intră în for-uri la fiecare iteraţie x şi y sunt comparaţi cu width şi height. În cazul în care cele două mărimi sunt locale metodei, ele sunt declarate ca variabile în cache-ul procesorului, timpul de acces al variabilelor fiind cu cateva ordine de mărime mai mic decât în cazul accesării proprietăţii Height sau Width a obiectului Bitmap src.Aceasta trebuie adusă la fiecare iteraţie din memoria RAM pentru a se efectua comparaţia cu x si y.
Am ramas în mod plăcut surprins de această mică descoperire. Pentru a doua dată nişte cunosţinte învaţate la o materie (sisteme cu microprocesoare - SMP) în facultate au aplicabilitate in viaţa reală. Prima dată a fost reacţia (invaţată in mod serios la Teoria Sistemelor - TS) care m-a facut să observ fenomenele un pic altfel. Un algoritm care se foloseşte de reacţie pentru a fi adaptiv întotdeauna este încadrat în categoria SPECTACULOS.
Technorati tags: C#