Vad är snabbast - Två for-satser eller FFT2D för konventionell matrismultiplikation för Sobel?

Permalänk

Vad är snabbast - Två for-satser eller FFT2D för konventionell matrismultiplikation för Sobel?

Jag försöker optimera lite.

Antag att vi ska göra om denna bild

Till denna bild. Det bilden visar är gradienterna mellan olika pixlar. Det kan vara t.ex att om pixel 1 har värdet 0 (svart) och pixel 2 har värdet 255 (vit). Skillnaden mellan pixel 1 och pixel 2 är 255.

För att hitta gradienterna (skillnaden mellan pixlarna) så finns det Sobel, Canny, Prewitt, LoG, Roberts osv. Alla dessa ger olika egenskaper i bilden. Sobel ger egenskapen att man får en kontur runt om ett objekt, vilket jag vill ha.

För att hitta Sobel-gradienter från en bild så kan man antingen använda två stycken for-satser som itererar över varje pixel i varje bild. Eller så kan man använda FFT2D för att utföra konventionell matrismultiplikation. För konventionell matrismultiplikation så behövs en kärna K som är en matris som man "drar" över hela bilden. Kärnan är antingen en 3x3 eller 5x5.

Fråga:
Vem är snabbast för en bild som har M rader och N kolumner.

  • Konventionell matrismultiplikation med FFT2D som är hårdvaruoptimerad

  • Två for-satser för att iterera

I detta fall så handlar språket om C och mjukvaran Math Kernel Library eller CMSIS

Permalänk
Medlem

Det skulle förvåna mig om inte FFT2D är snabbare, men detta känns som ett lysande fall för en jämförelse! Implementera båda och testa

Permalänk

MKL är optimerat för att få ut det mesta möjliga ur (Intels) hårdvara. Det skulle förvåna mig oṁ du kan skriva något som är effektivare så länge du skall hålla dig till C.

Permalänk
Skrivet av Ingetledigtnamn:

MKL är optimerat för att få ut det mesta möjliga ur (Intels) hårdvara. Det skulle förvåna mig oṁ du kan skriva något som är effektivare så länge du skall hålla dig till C.

Ja, i detta fall använder jag FFT2D för att göra konventionell matrixmultiplikation.
Med lite enkel MATLAB-kod så kan man beskriva detta som

% Create kernel [m, n] = size(X); kernel = zeros(m, n); [m, n] = size(K); % Compute the sizes m_middle = ceil(m/2); n_middle = ceil(n/2); % Insert kernel kernel(1:m_middle, 1:n_middle) = K(m_middle:end, n_middle:end); kernel(end, 1:n_middle) = K(1, n_middle:end); kernel(1:m_middle, end) = K(m_middle:end, 1); kernel(end, end) = K(1,1); % Do FFT2 on X and kernel A = fft2(X); B = fft2(kernel); % Compute the convolutional matrix - real to remove zero imaginary numbers C = real(ifft2(A.*B));

Där C matrisen är själva utgången som man önskar.

Permalänk
Medlem

Den som skapar flest trådar om matrismultiplikationer innan den dör vinner.
heretic16, du kommer bli odödlig.

Permalänk
Medlem
Skrivet av iXam:

Den som skapar flest trådar om matrismultiplikationer innan den dör vinner.
heretic16, du kommer bli odödlig.

Jag är helt oinsatt i programmering men tycker det är intressant att läsa trådar som den här då det då och då blir riktigt intressanta diskussioner. även om jag inte förstår koden i sig gillar jag när folk resonerar med kunskap och erfarenhet i ryggen

Permalänk
Skrivet av tonii:

Jag är helt oinsatt i programmering men tycker det är intressant att läsa trådar som den här då det då och då blir riktigt intressanta diskussioner. även om jag inte förstår koden i sig gillar jag när folk resonerar med kunskap och erfarenhet i ryggen

Ja, det finns mycket kunnigt folk här, i alla fall på programmeringssidan typ web. Men när det kommer till optimering, algoritmer och matematik så är det dock en bristvara.

Permalänk
Medlem
Skrivet av tonii:

Jag är helt oinsatt i programmering men tycker det är intressant att läsa trådar som den här då det då och då blir riktigt intressanta diskussioner. även om jag inte förstår koden i sig gillar jag när folk resonerar med kunskap och erfarenhet i ryggen

Jag finner också att hans trådar brukar mynna ut i att jag har lärt mig åtminstone *någonting*.
Vad jag försökte skämta om är att *jag* tycker att man håller sig till en tråd och ett ämne och inte spammar ett forum med nya trådar inom samma ämne.
Men det är vad jag tycker och jag kan naturligtvis ha fel i det stora hela.

Sorry alla för lite offtopic, nu ska jag vara tyst.

Permalänk
Medlem

Nu är det ju ett tag sen jag läste kurser om faltning på LiU men om jag inte minns helt fel behöver man (i bakgrunden iaf) göra en rätt stor matris av kärnan om man ska applicera det som en enda matrismultiplikation. Det skulle isåfall kunna vara en anledning till att en loop går fortare, om overheaden att skapa matrisen är stor. Generellt är väl MM dock snabbare än loopar om man har med högnivåspråk som inte kompileras att göra.
Kommer inte ihåg alla begreppen tyvärr.

Permalänk
Skrivet av iXam:

Jag finner också att hans trådar brukar mynna ut i att jag har lärt mig åtminstone *någonting*.
Vad jag försökte skämta om är att *jag* tycker att man håller sig till en tråd och ett ämne och inte spammar ett forum med nya trådar inom samma ämne.
Men det är vad jag tycker och jag kan naturligtvis ha fel i det stora hela.

Sorry alla för lite offtopic, nu ska jag vara tyst.

Kan säga att skriver man något i en gammal tråd på detta forum, så svarar ingen. Det är bara i nya trådar som folk svarar. Därför skapar jag ny tråd.

Skrivet av Napoleongl:

Nu är det ju ett tag sen jag läste kurser om faltning på LiU men om jag inte minns helt fel behöver man (i bakgrunden iaf) göra en rätt stor matris av kärnan om man ska applicera det som en enda matrismultiplikation. Det skulle isåfall kunna vara en anledning till att en loop går fortare, om overheaden att skapa matrisen är stor. Generellt är väl MM dock snabbare än loopar om man har med högnivåspråk som inte kompileras att göra.
Kommer inte ihåg alla begreppen tyvärr.

När jag läser teorin om att utföra Sobel så är det ganska mycket. Det är egentligen inte bara ta differensen mellan två olika pixlar. Det är lite mera matematik.

Jag vet dock inte om det att jämföra två pixlar i taget, eller om man måste summera pixlarna.

Permalänk
Medlem

Om det inte handlar om väldigt små bilder så är nästan säkert Math Kernel Library snabbare än naiva nestade for-loopar, det är nog inte orimligt att skriva ett snabbare sobel-filter själv, men du får ta till mer än bara ett par loopar, det bör ju t.ex. vara nära trivialt att tråda detta. Men beroende lite på vad det är för bilder och hur många av dom så skulle jag säga att en CUDA implementation bör vara det som är snabbast om det ska köras på en någorlunda normal desktop maskin (om den har ett nvidia grafikkort).

Handlar det om bara en enskild 300x255 bild som ska filtreras så lär det snabbaste vara typ Photoshop eller GIMP.

Visa signatur

I just love the fact that there is a global integer variable named 'i'. Just think, you will never need to declare your loop variable again!
To avoid collisions where a loop that uses 'i' calls another function that loops with 'i', be sure to stack 'i' and restore it when your function exits.