Párhuzamos programozás GPU
2016-06-05T11:15:50+02:00
2016-06-06T13:48:17+02:00
2022-08-10T04:40:30+02:00
tuzvolte
Sziasztok!

Mostanában kezdtem el ismerkedni az OpenGl programozással c++ nyelven.
Írtam egy alkalmazást ami HD felbontásban számolja ki egy-egy pixel színét random függvénnyel.
Ez így még az erős grafikus kártyámmal is lassan fut le, azt szeretném megtudni, hogy hogyan tudnám GPU-ra párhuzamosítva megírni, hogy minden egyes videókártyás mag egy egy pixelt számoljon, amíg a végére nem érnek. Egyáltalán lehetséges-e hiszen c++-os rand() függvény is kell ahhoz, hogy egy egy pixel színét kiszámolja. :)

Előre köszönöm! :)

Dávid
Mutasd a teljes hozzászólást!
Azok a jól párhuzamosítható algoritmusok, ahol az egyes szálaknak kevés közük van egymáshoz.
A gond az, hogy bár te biztos el tudod képzelni, hogy fogsz egymillió dobókockát és egyszerre dobsz velük, a számítógépek a véletlenszámokat egymásból számolják, sorban egymás után. Itt egy tipikus algoritmus: Linear congruential generator - Wikipedia, the free encyclopedia - a táblázatban láthatod, hogy különféle C/C++ implementációk és a Java is ezt használják.
Triviális fixen párhuzamos megoldás szerintem nincs a feladatodra.
Olyat biztosan lehet, hogy felezgeted a feladatot (generálsz két véletlen számot és ezeket seedként használva töltöd fel a rész/kép két felét véletlen-számokkal - lehet, hogy működik egy véletlenszám-generáló algoritmussal is, de ha kettőt váltogatsz, az valószínűleg jobb eredményre vezet), csak ez meg már dinamikus párhuzamosítást igényel (a feladat-felezés részeként a szálból indítani kell legalább egy új szálat), ami a GPU-nak nem erőssége.
Mutasd a teljes hozzászólást!

  • Írtam egy alkalmazást ami HD felbontásban számolja ki egy-egy pixel színét random függvénnyel. Ez így még az erős grafikus kártyámmal is lassan fut le,

    Azért fut le lassan, mert egészen biztos nem a videókártyán futott ;)

    azt szeretném megtudni, hogy hogyan tudnám GPU-ra párhuzamosítva megírni, hogy minden egyes videókártyás mag egy egy pixelt számoljon, amíg a végére nem érnek.

    Ha a grafikai dolgok mellett szeretnél maradni és nem valami általános célú dolgot akarsz számoltatni. a válasz rá a GLSL (ez egy programozási nyelv amit opengl alatt a gpu programozására használhatsz). A másik kulcsszó a fragment shader lesz.

    Egyáltalán lehetséges-e hiszen c++-os rand() függvény is kell ahhoz, hogy egy egy pixel színét kiszámolja. :) 

    A c++ -os rand() függvényt nem fogod tudni használni, mivel a GPU-t GLSL-ben fogod tudni programozni
    Mutasd a teljes hozzászólást!
  • Azok a jól párhuzamosítható algoritmusok, ahol az egyes szálaknak kevés közük van egymáshoz.
    A gond az, hogy bár te biztos el tudod képzelni, hogy fogsz egymillió dobókockát és egyszerre dobsz velük, a számítógépek a véletlenszámokat egymásból számolják, sorban egymás után. Itt egy tipikus algoritmus: Linear congruential generator - Wikipedia, the free encyclopedia - a táblázatban láthatod, hogy különféle C/C++ implementációk és a Java is ezt használják.
    Triviális fixen párhuzamos megoldás szerintem nincs a feladatodra.
    Olyat biztosan lehet, hogy felezgeted a feladatot (generálsz két véletlen számot és ezeket seedként használva töltöd fel a rész/kép két felét véletlen-számokkal - lehet, hogy működik egy véletlenszám-generáló algoritmussal is, de ha kettőt váltogatsz, az valószínűleg jobb eredményre vezet), csak ez meg már dinamikus párhuzamosítást igényel (a feladat-felezés részeként a szálból indítani kell legalább egy új szálat), ami a GPU-nak nem erőssége.
    Mutasd a teljes hozzászólást!
  • És tényleg! Nem gondoltam bele, hogy a random hogyan működik, akkor megpróbálom más oldalról megközelíteni a dolgot. köszönöm! :)
    Mutasd a teljes hozzászólást!
  • Azert egy sistergos tv effekt nem kene, hogy kifogjon rajtunk rogton az elejen...

    En az xy poziciobol indulnek ki, ahhoz hozzaadnek egy konstanst, ami minden kepkockanal mas erteket venne fel, majd erre a seed-re rakuldenek egy egyszeru random generatorbol egyetlen round-ot. Mivel glsl-ben nem igazan lehet 32bit egeszeket szorozni, meg leszedni az erednenybol a felso 32bitet, emiatt inkabb egy egyszerubb 16bites rng-t hasznalnek.

    A rand fuggveny csak cppbol elerheto. -> Akkor irj sajatot XD
    Mutasd a teljes hozzászólást!
  • Évente egyszer feltolom a valagam prog.hu -ra, de minden alkalommal ismételten rájövök, hogy miért is nem járok ide.
    Ez a válasz ez komoly? Se a kérdésekre nem reagáltál, se értelmes választ nem írtál (nettó hülyeséggel van tele, de tényleg), erre a kérdező elfogadja helyesnek.
    Sebaj, majd egy év múlva! :P
    Mutasd a teljes hozzászólást!
  • GLSL hashItt a shadertoy-on egy csomó példát találhatsz a véletlenszerű megoldásokra, álltalában hash-nak hívják. A glsl fragment shader-ben amivel itt lehet játszani elsőre annyit érdemes tudni, hogy a 

    void mainImage( out vec4 fragColor, in vec2 fragCoord )

    függvény minden pixelre lefut jó esetben 60 fps-el.
    Mutasd a teljes hozzászólást!
  • Igaz. Poénból megpróbáltam WebGL-el, de kiderült (persze hosszadalmas szívássorozat után), hogy a Chrome WebGL-e még mindig 1.0-s, nincs benne egész típus, se bitműveletek.
    StackOverflow-ról puskázva a random-helyettesítést ilyen lett:

    <!DOCTYPE html> <html> <head> <title>Stuff</title> <script> function start() { var gl=document.getElementById("glcanv").getContext("webgl"); var vs=gl.createShader(gl.VERTEX_SHADER); var fs=gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(vs,"attribute vec2 coords;varying vec2 pos;void main(void){pos=coords;gl_Position = vec4(coords, 0.0, 1.0);}"); gl.shaderSource(fs,"precision mediump float;varying vec2 pos;void main(void){float rand=fract(sin(dot(pos.xy,vec2(12.9898,78.233)))*43758.5453);gl_FragColor=vec4(rand, rand, rand, 1);}"); gl.compileShader(vs); gl.compileShader(fs); var prg=gl.createProgram(); gl.attachShader(prg, vs); gl.attachShader(prg, fs); gl.linkProgram(prg); gl.useProgram(prg); var vertices=[-1,-1,1,-1,1,1,-1,1]; var indices=[0,1,2,3]; var vertexbuff=gl.createBuffer(); var indexbuff=gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, vertexbuff); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexbuff); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW); var coords = gl.getAttribLocation(prg, "coords"); gl.vertexAttribPointer(coords, 2, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(coords); gl.clearColor(0,0,0,1); gl.clear(gl.COLOR_BUFFER_BIT); gl.drawElements(gl.TRIANGLE_FAN, indices.length, gl.UNSIGNED_SHORT,0); } </script> </head> <body onload="start()"> <canvas id="glcanv" width="500" height="500"></canvas> </body> </html>
    Mutasd a teljes hozzászólást!
  • Jó-jó.

    nettó hülyeséggel van tele, de tényleg

    Hátő, izé. Azért volt benne igazság is.

    Sebaj, majd egy év múlva! :P

    Várunk majd 
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd