Seite 1 von 2
Rechenintensive Prozesse auf GPU auslagern
Verfasst: 26.02.2012 17:27
von Sunny
Hi@all,
ich hoffe, dass der Betreff meines Anliegens richtig gewählt ist...
Gleich mal zu meinem Problem.
Ich habe hier mal einen kleinen Code:
Code: Alles auswählen
min = 1
max = 1000000
qs = 17
For i = min To max
Value$ = Str(i)
value = 0
For n = 1 To Len(Value$)
value + Val(Mid(Value$, n, 1))
Next
If value = qs
x + 1
EndIf
Next
Debug "Zwischen " + Str(min) + " und " + Str(max) + " gibt es " + Str(x) + " Zahlen, deren Quersumme 17 ist."
Dieser Code funktioniert ja tadellos und und wenn die Variable "max" einen Wert von "1.000.000" hat, ist das auch in einigen Sekunden durchgelaufen.
Wenn ich jetzt allerdings den Wert von "max" auf "100.000.000" setze, sieht die sache schon ganz anders aus.
Jetzt wollte ich mal wissen, ob ich mit PB die Grafikkarte ansprechen kann um diese Berechnung (Zähling / Inventierung / was auch immer ^^) auf die GPU auszulagern?
Wenn das möglich ist, wie müsste dann der Code dafür aussehen?
Re: Rechenintensive Prozesse auf GPU auslagern
Verfasst: 26.02.2012 17:47
von STARGÅTE
Meiner Meinung nach würde es schon mal viel brinden, wenn du diesen Code beschleunigst.
Das heißt alle String-Funktionen raus nehmen und nur mit Zahlen arbeiten!
Die Zahl kannst du auch numerisch in ihre Ziffern aufteilen
Danach ist der Code schon mal ca 200 mal schneller!
Danach kannst du noch überlegen die Min-Max sache auf mehrere zwischen Intervalle auf Theads aufzuteilen.
dann kannst du mehrere Prozessoren benutzen.
Re: Rechenintensive Prozesse auf GPU auslagern
Verfasst: 26.02.2012 17:49
von c4s
Probier es mal
ohne Debugger (komplett ausgeschaltet!) und entferne die Stringfunktionen. Sonst gibt es eventuell hier etwas für dein Anliegen:
http://www.purebasic.fr/german/viewtopic.php?t=19399
Re: Rechenintensive Prozesse auf GPU auslagern
Verfasst: 26.02.2012 17:52
von Sunny
Ähm...
Tut mir leid, dass ich mich diesbezüglich etwas unverständlich ausgedrückt hab.
Es geht mir hierbei nicht um diesen Code (der diente bloß als ein halbwegs sinnvolles Beispiel).
Mir geht es hauptsächlich um das ansprechen der GPU.
Edit:
@c4s - Sieht ganz nett aus, hilft mir aber leider nicht so wirklich weiter, da diese Library nur vordefinierte Operationen (Berechnungen oder was auch immer) ausführt. Ich möchhte mir aber eigene Dinge auf kosten der GPU durchrechnen lassen.
Re: Rechenintensive Prozesse auf GPU auslagern
Verfasst: 26.02.2012 18:05
von STARGÅTE
Trotzdem solltest du dir überlegen, ob es überhaupt sinnvoll ist, die GPU mit ggf. "Müll" zu belasten.
Die GPU würd wohl nicht sehr glücklich sein, wenn es darum geht, zB einen Text nach Rechtschreibfehler zu durchsuchen, um das mal auf die Spitze zu treiben, wenn du weißt was ich meine.
Der Vollständigkeithalber hier mal eine schnellere Variante
Code: Alles auswählen
Procedure DigitSum(Value.i)
Protected Total.i
Repeat
Total + Value%10
Value/10
Until Value = 0
ProcedureReturn Total
EndProcedure
Define Min = 1
Define Max = 1000000
Define DigitSum = 17
Define Count.i
For Number = Min To Max
If DigitSum(Number) = DigitSum
Count + 1
EndIf
Next
MessageRequester("", "Zwischen " + Str(Min) + " und " + Str(Max) + " gibt es " + Str(Count) + " Zahlen, deren Quersumme "+Str(DigitSum)+" ist.")
Re: Rechenintensive Prozesse auf GPU auslagern
Verfasst: 26.02.2012 18:12
von Sunny
OK...
Um weitere Diskusionen über die Richtigkeit meines Codes zu vermeiden, nehmen wir jetzt einfach mal STARGÅTE's Code als Beispiel... ^^
Dennoch bleibe ich bei meiner Frage, wie man das auf die GPU auslagern kann?
Re: Rechenintensive Prozesse auf GPU auslagern
Verfasst: 26.02.2012 18:14
von DarkDragon
Sunny hat geschrieben:@c4s - Sieht ganz nett aus, hilft mir aber leider nicht so wirklich weiter, da diese Library nur vordefinierte Operationen (Berechnungen oder was auch immer) ausführt. Ich möchhte mir aber eigene Dinge auf kosten der GPU durchrechnen lassen.
Nein, du kannst doch selbst ein Skript definieren, das dir das ganze berechnet.
Re: Rechenintensive Prozesse auf GPU auslagern
Verfasst: 26.02.2012 18:20
von Sunny
Nein, du kannst doch selbst ein Skript definieren, das dir das ganze berechnet.
Eben nicht, das ist ja das Problem ^^
Ich hab halt keine Ahnung, wie ich die Grafikkarte für solche Berechnungen ansteuere.
Vieleicht muss ich mich dafür ein bischen mit Assembler oder so befassen? Keine Ahnung...
Re: Rechenintensive Prozesse auf GPU auslagern
Verfasst: 26.02.2012 18:58
von DarkDragon
Gut, dieses eine Problem lässt sich mit der oben genannten Bibliothek nicht gut beschleunigen, aber um zu beweisen, dass es überhaupt geht und dass du sehr wohl ein eigenes Skript verfassen kannst:
Code: Alles auswählen
XIncludeFile "GPUCalc.pbi"
Procedure WaitForLastCommand(*context.GPUCalcContext)
Protected result
result = 1
While Not *context\hasFinishedLastCommand()
gpuCalcYield()
Wend
If Not *context\wasLastCommandSuccessful()
Select *context\getLastErrorCode()
Case #GPUCALC_ERR_NO_ERROR
PrintN("#GPUCALC_ERR_NO_ERROR")
Case #GPUCALC_ERR_RENDERINGCONTEXT
PrintN("#GPUCALC_ERR_RENDERINGCONTEXT")
Case #GPUCALC_ERR_MULTITEXTURING
PrintN("#GPUCALC_ERR_MULTITEXTURING")
Case #GPUCALC_ERR_SHADERS
PrintN("#GPUCALC_ERR_SHADERS")
Case #GPUCALC_ERR_FRAMEBUFFEROBJECTS
PrintN("#GPUCALC_ERR_FRAMEBUFFEROBJECTS")
Case #GPUCALC_ERR_VERTEXBUFFEROBJECTS
PrintN("#GPUCALC_ERR_VERTEXBUFFEROBJECTS")
Case #GPUCALC_ERR_COMPILE_VERTEX
PrintN("#GPUCALC_ERR_COMPILE_VERTEX")
PrintN(PeekS(*context\getCompilerErrorVertex()))
Case #GPUCALC_ERR_COMPILE_FRAGMENT
PrintN("#GPUCALC_ERR_COMPILE_FRAGMENT")
PrintN(PeekS(*context\getCompilerErrorFragment()))
Case #GPUCALC_ERR_LINK_SHADERS
PrintN("#GPUCALC_ERR_LINK_SHADERS")
PrintN(PeekS(*context\getLinkerError()))
Case #GPUCALC_ERR_FLOATTEXTURE
PrintN("#GPUCALC_ERR_FLOATTEXTURE")
Case #GPUCALC_ERR_INTEGERTEXTURE
PrintN("#GPUCALC_ERR_INTEGERTEXTURE")
Case #GPUCALC_ERR_INVALIDDATATYPE
PrintN("#GPUCALC_ERR_INVALIDDATATYPE")
EndSelect
result = 0
EndIf
ProcedureReturn result
EndProcedure
OpenConsole()
Define *initialContext.GPUCalcContext
Define *context.GPUCalcContext
Define code.s = ""
code + "int calcDigitSum(int i)" + #LF$
code + "{" + #LF$
code + " int result = 0;" + #LF$
code + " while(i > 0)" + #LF$
code + " {" + #LF$
code + " int nextI = (i / 10);" + #LF$
code + " result += i - 10 * nextI;" + #LF$
code + " i = nextI;" + #LF$
code + " }" + #LF$
code + " return result;" + #LF$
code + "}" + #LF$
code + "ivec4 calc(int startOffset)" + #LF$
code + "{" + #LF$
code + " int result = 0;" + #LF$
code + " if(startOffset == 0) {" + #LF$
code + " int digitSum = 17;" + #LF$
code + " for(int i = 1; i < 1000000 - min(startOffset, 1) * 1000000; i ++) {" + #LF$
code + " if(calcDigitSum(i) == digitSum) {" + #LF$
code + " result ++;" + #LF$
code + " }" + #LF$
code + " }" + #LF$
code + " }" + #LF$
code + " return ivec4(result, 0, 0, 0);" + #LF$
code + "}" + #LF$
If LoadGPUCalcSymbols()
*initialContext = gpuCalcCreateContext(#GPUCALC_TYPE_FLOAT32, 0, 0)
If *initialContext
If WaitForLastCommand(*initialContext)
If Not *initialContext\integerCalculationSupported()
PrintN("Your gpu isn't able to handle integers")
Else
*context = gpuCalcCreateContext(#GPUCALC_TYPE_INT32, 0, 1)
WaitForLastCommand(*context)
*resultMemory = *context\allocateDatasetMemory()
WaitForLastCommand(*context)
*context\loadCode(0, code, Len(code))
WaitForLastCommand(*context)
*context\bindCode(0)
WaitForLastCommand(*context)
*context\calculate(*resultMemory, 1)
WaitForLastCommand(*context)
PrintN("Result: " + Str(PeekI(*resultMemory)))
gpuCalcReleaseContext(*context)
EndIf
EndIf
gpuCalcReleaseContext(*initialContext)
EndIf
ReleaseGPUCalcSymbols()
Else
PrintN("Error: couldn't open the library.")
EndIf
Input()
End
Re: Rechenintensive Prozesse auf GPU auslagern
Verfasst: 26.02.2012 22:56
von Kiffi
<OT>
STARGÅTE hat geschrieben:Trotzdem solltest du dir überlegen, ob es überhaupt sinnvoll ist, die GPU mit ggf. "Müll" zu belasten.
Die GPU würd wohl nicht sehr glücklich sein, wenn es darum geht, zB einen Text nach Rechtschreibfehler zu durchsuchen, um das mal auf die Spitze zu treiben, wenn du weißt was ich meine.
auch mal ein interessanter Aspekt der Programmierung.

Also werde ich mir
in Zukunft gut überlegen müssen, ob ich meinen sensiblen Prozessoren
meinen Code zumuten kann.
</OT>