(Hogy a .......)Grafikus memória direkt címzése. (Szóval overlay)

 ( emberk | 2009. január 21., szerda - 20:50 )

Sziasztok.

A címben megadott témában kellene valami jó kis doksi. (A Google a barátom tudom, de jelenleg cserbenhagyott) Az igazi az lenne ha C alapok lennének de jó asm és c++ is. Írtam egy képelemző programot, és az vele a gáz, hogy a proci akkor is 40-50%-on megy ha csak dobja a video-t. Szóval igen komoly sebességnövekedést érnék el egy direkt memória címzéssel.
Ja és linux alá természetesen.
Előre is köszönöm.

Szerk:
A fene gondolt erre vacak a kamera kernelmodulja. Na mindegy a lényeg, hogy megoldódni látszik a probléma, ugyanis akármivel nézem ezt a kamera képet azzal is 40-50%-on eszi a gépet. Rászurtam egy másik (típusú) kamerát a gépre és azzal gyönyörűen kb 3-6%-on eszi a gépet. Szóval megszivattam saját magam.Azért köszönöm a segítséget.

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

Valós / Védett módban? VESA-ban? milyen felbontással/színmélységgel?

640*480 nvidia kártya (nem kell hogy hordozható legyen a kód, ezen az 1 gépen kell futnia). A valós vagy védett az mindegy, ahogy könnyebb megvalósítani. (ASM ben nem vagyok nagy ász sajnos egyenlőre). Ja és a színmélység az gyak tetszőleges az lenne, lejobb ha 256 szintű fekete fehér lenne.

ah látom linux alá kellene. Nem hiszem, hogy a kernel hagyná, hogy Te csak úgy "belepiszkálj" a memóriába.
Ha jól tudom, az MPlayer tud ilyet: http://svn.mplayerhq.hu/mplayer/trunk/libvo/vesa_lvo.c?revision=27541&view=markup

A 640*480 -esből a VESA 256-szinüt(1byte/pixel) támogat. (ez a 0x100 -as)

Köszönöm. Megnézem mire jutok belőle.

Ebben a könyvben le van írva, a VESA kezelése valós és védett módban is:
http://www.kiskapu.hu/index.php?BODY=BookInfo&OP=details&ID=50938

És OpenGL nem jó? az nem elég gyors?

Látod az opengl eszembe sem jutott. Lehet az is elég lenne csak az van hogy openglt nem tanultam soha. (Az az igazság, hogy én nem is programozó vagyok hanem fizikus, csak magamtól megtanultam C-programoznizni és ASM-ezni amiennyi nekem kellet) de nem rossz ötlet az opengl. Amennyi nekem kell az biztosan nem sok. Megnézem ezt a könyvet.

OpenGL elég egyszerű. A Dev-C++ program mellé adott példákból gyorsan lehet tanulni. És ha jól tudom, akkor ezt a videókártya is "gyorsítja"

sdl szvsz meg egyszerubb, es talan neki az is eleg.
--

()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.

bármire vevő vagyok. Nekem a lényeg a matek elemzés. az sdl is hardweresen gyorsított?

Naná. Én sdl-hez nem értek, de példakódok alapján egyszerű. Én régebben tanultam opengl-t (glut-tal megtámogatva), az se nehéz.

az fb dev-en keresztul valahogyan tudod mmap-elni a framebuffer-t
xorg is ezt csinalja

--
When in doubt, use brute force.

Én a DirectFB-re gondoltam elsőre de ott nem jutottam előrébb. Megnézem ezt is.

Én DGA-val nyúlnék a dologhoz első közelítésben.

> Sol omnibus lucet.

+1
elvileg SDL-lel is lehet hasznalni DGA-t (az volna a legkenyelmesebb) nekem azt hiszem nem igazan sikerult mukodesre birni (ment csak szerintem nem dga-val), neked talan jobban megy.

szerk: u.i.: dga-hoz azt hiszem rootnak kell lenni.

- Use the Source Luke ! -

a /usr/include/asm segíthet.
OpenGL doksi van letölthető, linket hirtelen nem tudok.

miben segit az /usr/include/asm ? nem hiszem, hogy attol hajlando lenne nalam az SDL dga-t hasznalni.

amugy most kiprobaltam az mplayer -vo dga-t, attol lehalt az X ugy, hogy ujra se lehetett inditani (nem volt tobbet kep). szoval driver fuggo lehet a dga hasznalhatosaga (pl. nvidia-ra is azt irtak, hogy nem megy - nekem mondjuk ati fglrx van), de talan az opensource driverekkel megy.

- Use the Source Luke ! -

Nagyon jó OpenGL példák itt: http://nehe.gamedev.net/

--
Kinek nem inge, ne vegye gatyára

Amúgy assembly-hez nem kell ma már nyúlni (speciális eseteket kivéve). Egy jól megírt C++ program hozza a megfelelő sebességet, mégis magasabb szintű, mintha direkt opkódokat írnál :)

--
Kinek nem inge, ne vegye gatyára

Es jo esetben nem kell a portabilitassal se vacakolni :)
--

()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.

Hát nem tudom. Én meg azt olvastam sokszor, hogy az asm és a C közöt is egész komoly tempókülömbségek vannak (akár 2-3*-os is, lehet nem igaz, de ilyen utalások voltak). Ami kérdéses, hogy mennyit nyer vele az ember mert jóval lassabban lehet kifejleszteni így a kódot, és így summa lassabban lehet kész az eredmény.

Vegyük egy átlagos fejlesztő C tudását 1-nek.

Egy komolyabb fejlesztő aki kicsit is odafigyel a hatékonyságra, gyorsabb kódot ír: 1.5-2

Ehhez képest asm-ben, mély tudással az adott processzorrol: 2-5 (x86 esetén inkább 2-3).

Persze ez nem azt jelenti, hogy a C kódot egy az egyben megírod asm-ben, annál még a Gcc is jobb kódot generál. Ilyenkor már utasítások sorrendjét kell variálni, ciklusokat "kicsomagolni" (loop-unrolling), stb. Ezek egyrésze C-ben is működik, nagy része pedig mély tudást feltételez a processzor működéséről.

Amíg ez a tudás nincs meg, bőven jó a C, ha gyorsítani akarsz, SSE-nek nézz utána...

(Mind az intel, mind az amd honlapján vannak ilyen témájú leírások, a leírások elején általános (C-s) trükkök, később specifikusabb ötletek. Plusz mindkét cégnél vannak profiler szoftverek.)

Egyébként "a korai optimalizáció a legtöbb baj forrása".
Tehát írd meg C-ben, profiler programokkal, saját mérésekkel keresd meg a leglassab részt, módosíts az algoritmuson ha lehet (itt vannak nagyságrendbeli gyorsítási lehetőségek), optimalizáld C-s trükkökkel, SSE, asm.
Állj meg, ha elég gyors. :)
Asm-től ne várj csodákat...

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o

viszont hatekony sse kodot tenyleg nem tud csinalni a compiler, oda kell az asm, illetve lehet eloszor intrinsicekkel probalkozni (de az mar eleg kozel van az asmhoz).

- Use the Source Luke ! -

persze én sem csodákat várok tőle hogy egy P2-es eléri a mai gépek sebességét, csak ha kell akkor. Így is megy a program amit csináltam, csak nem valami fenemód praktikusan, elég sokat pocsékolok. Gondoltam egy kicsit csinosítanék rajta.

Igen, az a bizonyos 80-20 szabaly: Az ido 80 szazalekaban a kod 20 szazaleka fut le.
--

()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.

Ez nálam nagyon igaz lennesz. Mert ha beindul az elemző motor akkor kb a kép megjelenítés ideje 40% a modul 60%. Ha elérem ezzel az opengl vagy sdl kombóval a 80/20-at akkor ok. Nem küzdök vele tovább.

Vagy én nem értem amit mondasz, vagy te nem érted a 80-20-as szabályt. :)

A szabály arról szól, hogy egy átlagos programnak vannak olyan részei amik ritkán futnak, és vannak olyan részei, amik gyakran.
Azaz a program 20%-a fut az idő 80%-ában.

Ebből következik, hogy semmi értelme az egész programot optimalizálva írni, elég azt a bizonyos 20%-ot.

(De ez a 20% nem mindig az, amit mi annak gondolunk. Ezért érdemes először szépen tisztán kódolni, mérni, majd ezután optimalizálni.)

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o

Én régebben SDL-t használtam ilyen célra, mert nagyon praktikus, hogy lehet állítani, milyen API-t használjon maga alatt.
Simán lehet fejleszteni X alatt, aztán a végeredményt futtathatod akár framebufferen is.

http://asm.sourceforge.net/articles/fb.html
http://www.ummon.org/Linux/API/Devices/framebuffer.html

Foglalsz két buffert; az egyikre rajzolsz, amíg másik megjelenít,
és kapcsolgatsz a két buffer között...

:-)

Ize... en meg mindig tartom az elkepzelest, hogy a topicnyitonak egyelore eleg lesz a OGL/SDL duo is.
--

()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.

Nem ertek hozza, de szerintem ha egy folyamatosan valtozo _kepet_ akar kirajzolni, azt OpenGL-lel csak ugy tudja megtenni, ha folyamatosan feltolti texturakent, ami minden, csak nem gyors. (Annyi elonye lehet, hogy a driverben jobban meg lehet irva ez a feltolto resz, esetleg DMA-t is hasznalhat, nVidia kartyan, nem tudom.) Az SDL meg megintcsak lassu, konkretan. Nem kicsit, nagyon.

Amennyire en tudom, Linuxon nincs normalis modszer a videomemoria kozvetlen eleresere, ami mezei userkent is megy, es rendesen interaktal ilyen nagyobb rendszerekkel mint az X11 es tarsai. Kozvetlen durrbele hekkek es framebuffer magiak persze vannak, de azokra sokminden eszembe jut, csak az nem, hogy szep megoldas...

-=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

Akkor felejtős a dolog?

Nem feltetlenul, azert mindenre van megoldas, es Linuxra is lehet viszonylag gyors videokezelest irni, de ilyen konkretan pont nincs, hogy visszakapod egy memoriaterulet cimet, es oda renderelsz, es az egybol latszik a kepernyon is, a'la VGA $A000:0000. :) Mivel nem tudjuk jelenleg milyen modszert hasznalsz, milyen a kod, es az mit csinal, mig 40-50%-ot visz, ez a 40-50% mekkora kepet, milyen szinmelysegben es foleg: milyen gepen es milyen framerate-tel jelent, ezert eleg nehez tippeket adni. Ezzel csak azt akartam mondani, hogy nem hiszek a fenti "hasznalj SDL-t" meg "hasznalj OpenGL-t" varazsmodszerekben. Foleg mert lattam mar SDL kodot, amit sajat kezuleg gyorsitottam haromszorosara (ami meg mindig lassabb volt mint kene, de azert eleg latvanyos valtozas volt), tovabbra is csak SDL hasznalataval... Mindenben lehet lassut es gyorsat is irni...

-=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

Egyebkent, peldaul, azt irod, visszaolvasva, hogy 640x480 fekete-feher kepet akarsz kirakni. Tulajdonkeppen a blittelo rutinok sebesseget meghatarozza szinte minden rendszeren, hogy kell-e kozben szinmelyseg-konverziot vegezni. Ha pl. egy truecolor-ba allitott videokartyara renderelsz egy 256 szinu palettas kepet, akkor az lehet, hogy nem lesz gyors. Viszont ha ugyanannak a blittelo X11 vagy barmilyen mas fuggvenynek egy olyan szinmelysegu (es pixelformatumu! nem mindegy hogy BGRA vagy ARGB peldaul) buffert adsz, mint a kepernyo, akkor lehet hogy 40-50% helyett 1-2% procival fogja elvegezni a blittelest. Csak tipp, de ki kellene probalni. Ilyenkor ugyan neked kell konvertalni, de akkor bevethetsz mindenfele assembly magiat, es megirhatod gyorsra, nem vagy a driver/X11 kodjara, es annak potencialis lassusagara utalva. Ilyesmi jut eszembe elsore...

-=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

Az eddigi megoldásom unicap-imaging könyvtárát használja. Roppant egyszerű, de vele együtt iszonyú lassú is. megnézem hogy találok e más módszert, de itt nagyon sok jó tanácsot kaptam biztosan találok valamit közöttük. Ez az sdl, és OpenGL annyira egyszerűnek tűnik ami nekem kell az egészből, hogy ezeket kipróbálom, ha nem jön be keresek tovább. De köszönöm szépen az ötletet.

Azt nem vágom, hogyha írsz egy akármilyen feldolgozó algoritmust, akkor pixelenként eleve elhasználsz pár száz vagy ezer órajelet a pixel értékének kiszámításához. Ahhoz képest, hogy userspace memóriában állítod össze a képet és a driver másolja a videokártyára, mindössze egy másolást tudsz megspórolni azzal ha eleve a videokártyára írod. Ráadásul ez egy folytonos címtartományról folytonos címtartományra másolás amiket általában a hardver eléggé hatékonyan megold.

Tehát értelmes becslés szerint maximum pár százaléka lehet a teljes terhelésnek, amit meg tudnál ezzel a trükkel spórolni. Inkább vegyél egy erősebb gépet néhány tízezerér azt kész.

Idézet:
Tehát értelmes becslés szerint maximum pár százaléka lehet a teljes terhelésnek, amit meg tudnál ezzel a trükkel spórolni.

Az elmelet ott bukik, hogy valoszinuleg szinmelyseg-konverzio is tortenik a blitteles kozben, es ezert lassu, tehat innentol sem linearis teruletekrol, sem hardveres masolasrol nem beszelhetunk. Lasd fent.

Idézet:
Inkább vegyél egy erősebb gépet néhány tízezerér azt kész.

Es igy keletkeznek a slideshow-nezegetok, aminek 4 magos proci es masfel giga RAM kell, maskepp beszaggat. Igaz C64-re meg lehetne irni, de inkabb vettek erosebb hardvert! Szanalmas.

-=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

Én is inkább azon gyanakszom, hogy ez az én hibám. Valamit nem gondoltam át megfelelően stb. A Gép egyébként nem egy erőmű p4 2.2 celeron, de nem létezik, hogy ennyire ne bírna egy ilyen egyszerű feladatot. És még a matek modul nem is megy. Az mplayer meg röhögvel lejátszik rajta bármilyen agyontömörített filmet, egy sima "webkamerakép" megjelenítése meg eszi 50%-al a procit. Ez nem a vas hibája.

Ez bizony nem...

Win alatt .Net-tel és Qt-val is csinálok hasonlót, mindkettőben a beépített képmegjelenítőt használva (azaz a webcam képét még át is kell alakítanom BGR-ről RGB-re, és a sorokat is fel kell cserélni), még egy 1.6-os laptopon sem érem el az 5%-ot... (Igaz 320x240, kb 15fps.)

Valamit tuti elrontasz.
(Egyébként OpenCV-t ismered? Szerintem az kéne neked...)

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o

Én az unicap-imaging-et használom. Ismered?

Sose láttam... Ettől még lehet jó.

Ahogy nézem erőssége inkább a capture. De gyanus, hogy nem a lib hibája a sebességgondod...

OpenCV eléggé de facto szabvány a maga területén, elsősorban gépi látás területéhez kapcsolódo algoritmusok vannak benne. (Az élkiemeléstől az objektumkeresésig.)
Van minimális capture, és megjelenítő api, annyi amennyi az ilyen feladatokhoz elég. Sebesség gondok viszont tuti nincsenek vele.

Eszembe jutott valami: biztos csak az új frame-eket rajzoltatod ki?
Nem lehet, hogy akkor is küldöd a frame-eket, amikor nincs is új?

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o

most nem azert de a 640x480@30fps pont nyolcszorosa savszelessegben a 320x240@15fps-nek, es 5%*8=40%.
amugy a webkamera kep megjelenitesenek sebessege nem mervado, mert az valoszinuleg yuv szinterben jon be es rgb-ben megy ki, a szoftver konverzio meg marha lassu. ha a szoftverkonverzio volt a gond, akkor SDL-lel konverzio nelkul (lasd SDL_ANYFORMAT flag az sdl_setvideomode-nak, de yuv-ot nem tud) eleg gyors lesz. ha ugy is lassu, akkor xvideo-val lehet megprobalni - csak az bonyolultabb -, mert bar az yuv szintert fogad es nem a rgb-t, a szurkearnyalatot nagyon egyszeru yuv-ban reprezentalni, hiszen az Y komponens a fenyerosseg (azaz arnyalat 0 es 255 kozott), az U meg V pedig 128 (vagy 127 vagy 0?), es akkor pont szurket kapunk.
es persze mint fentebb irtam lehet probalkozni a DGA-val rootkent, akar SDL-en keresztul is, de az lehet, hogy tenyleg nem a legszebb megoldas, ha egyaltalan mukodik.

- Use the Source Luke ! -

Mondom: _nem_ érem el az 5%-ot, C#-ban .Net-tel!

Egyébként webcammal elérhetetlen a 30fps...

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o

Ha mar itt tartunk, biztos, hogy a megjelenites viszi az idot? :) Nem lehet, hogy fos a webcam driver, es a kep gepbe juttatasa zabal ennyit? :)

Szerk: haha, es ebben a pillanatban frissult a topic cime. Igy legyen otosom a lotton! :)

-=- Mire a programozó: "Na és szerintetek ki csinálta a káoszt?" -=-

3-6%... Naugye...

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o

Hát hallod mit össze szivattam magam :) Teljesen jól megy. Egy másik kamerával. Az ami nekem van (ergo a rossz) valami ucv drivert használ, és eddigi tapasztalatom alapján ez okozta a bajt. Ez meg valami kernelszinten támogatott ov51x vagy mi. Na a lényeg hogy HASÍÍÍÍÍT. :) :) :) :)

Töltöttél ki szelvényt?
--
unix -- több, mint kód. filozófia.
Life is feudal

De most gomolyan, 2.2-es Celeron nagyságrendileg 6000 MIPS.

640*480*30= 9,2 m

Ne tartson már 600 órajelig 1 pixel konvertálgatása és másolgatása, hogy a képernyőre kerüljön.
Vegyük már észre, hogy egy ilyen gép röhögve lejátszik egy 720p-s DivX-et, DGA nélkül...

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o

a 6000 mips nem tudom hogy jott ki, de amugy igazad van, 10% cpunal tenyleg nem nagyon ehetne tobbet maga a yuv2rgb konverzio meg ha optimalizalatlan brainfuckban is irtak volna meg.

- Use the Source Luke ! -

http://en.wikipedia.org/wiki/Million_instructions_per_second#Timeline_of_instructions_per_second

2.2 Ghz az eleve 2000 MIPS, de ugye a Pentium Pro óta túlvagyunk az 1 utasítás/órajelen...

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o

persze, de ha benan van megirva a kod, akkor egy szep hosszu dependency chain az egesz, es ugy nem nagyon fog egy orajel alatt tobb utasitast vegrehajtani a cpu. szoval rendben, az a 6000 amit irtal az az elmeleti maximum.

- Use the Source Luke ! -

Ezt hívják MIPS-nek... Egyébként nem elméleti (az ennél több lenne) SPECint-tel mérik...

Nyilván tudok olyan kódot írni, ami alatt a proci folyamatosan a memóriára vár...

De azért 600 órajel nekem elég soknak tűnt ahhoz, hogy ne fogjuk konvertálgatásra és másolgatásra...

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o

igen, nincs 600 orajel, hanem max kb. 20.

- Use the Source Luke ! -

Az XV mint olyan? azt hasznaljak a filmlejatszo progik is, optimalis esetben, X alatt legalabbis effektivebb, mint a sima nativ x+bufferele's. Es van egy rakat kvazi hardveresen tamogatott trafo is melle' (colormap-ek kozotti valtozgatas, yuv-trafok, nagyitas). libxv-dev. lehet hogy vki mar javallotta, ha wronly voltam akkor bocs.