1. Dashboard
  2. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team
    4. Mitgliedersuche
  3. Forenregeln
  4. Forum
    1. Unerledigte Themen
  • Anmelden
  • Registrieren
  • Suche
Alles
  • Alles
  • Artikel
  • Seiten
  • Forum
  • Erweiterte Suche
  1. AutoIt.de - Das deutschsprachige Forum.
  2. Mitglieder
  3. Andy

Beiträge von Andy

  • OpenCl goes AutoIt Update 31.Dezember 2016

    • Andy
    • 10. November 2014 um 13:11
    Zitat von Techmix

    >Gibst mir so eine Aufgabe, und wartest nichtmals das Wochenende ab...

    Der Standardspruch einer meiner Profs vor 30 Jahren zum Theme "zu wenig Zeit" war: "Was macht ihr nachts?" 8o

    Zitat von Techmix

    Wenn man eine Lastanalyse für einen Kernel auf allen Devices durchführen möchte, dann muß ich doch so vorgehen das der Kernel auf jedem Device einzeln für nur einige Durchläufe ausgeführt werden soll - dabei die Zeit stoppen.

    Ja, zwei Möglichkeiten: Erstens die Datengröße in "Teilstücke" ändern, dazu muss dem Kernel über einen Parameter der "Teiler" mitgegeben werden, problemlos!
    Zweitens die Anzahl der Workgroups über den zweiten Parameter bei _CL_RunKernel() (ist Standardmäßig null) einstellen. Das ist aber "finetuning", wenn OCL die verwendeten Workgroups festlegt, ist man eigentlich immer nah am Optimum!

    Zitat von Techmix

    Theoretisch kann man Kernel im vorraus so Planen, das diese Multi fähig sind.

    Das wäre natürlich optimal, macht aber nur dann Sinn, wenn die Kernellaufzeiten (reine Berechnungen auf der GPU) so lange dauern, dass der Overhead durch das weitere Übertragen des Speichers , also _CL_ReadBuffer(), nicht den Gewinn wieder auffrisst! Macht imho nur bei wirklich aufwendigen Berechnungen Sinn!

  • OpenCl goes AutoIt Update 31.Dezember 2016

    • Andy
    • 9. November 2014 um 19:57

    Ist schon klar :D
    Übrigens, u.a. lesenswert zum Thema SoA/AoS ein INTEL-Paper, welches eine 16-Core XEON-CPU mit einem 61-Core XEON-PHI vergleicht.
    Die Essenz "....if a code yields no vector speedup (no auto-vectorization that produces speedup) at
    all, then it is not very likely that Xeon Phi will ever exceed the performance of Intel Xeon even if it
    is fully parallel. That is, “highly parallel” is not enough to allow Phi to provide benefit in most cases.
    "
    lässt sich imho gut auf die Problematik "Code auf CPU oder GPU?" anwenden.

    Voraussetzung für gut auf der GPU verarbeitbaren Code ist Vektorisierung (4/8/16 "Schneebälle" werden durch SIMD/AVX IMMER gleichzeitig geworfen) , und zusätzlich noch Parallelisierbarkeit über den Algorithmus.


    @Techmix, ich glaube, nun ist es an der Zeit deine Idee von einem Packer/Komprimierer umzusetzen 8o

  • OpenCl goes AutoIt Update 31.Dezember 2016

    • Andy
    • 9. November 2014 um 19:03

    Ja, das geht natürlich auch, statt der atomics hat man dann die barriers...und muss zusätzlich nach dem Lesen des Output-Speicherbereichs noch alle Summen zusammenzählen. Wenn die "eigentliche" Anwendung nicht massiv parallelisierbare und bestenfalls float-Arithmetik nutzt, hilft das sicher auch nicht viel.

    Alles in allem stellt sich die Frage, ob man für solch triviale Aufgaben nicht eine CPU und SIMD mit einer SoA-Datenstruktur benutzt.
    Je nach Anwendung rockt dann ein CPU-Kern die tausenden GPU-Kerne. Cést la vie.

  • OpenCl goes AutoIt Update 31.Dezember 2016

    • Andy
    • 9. November 2014 um 17:17

    Lösung sind die sog. "atomic operations".
    Hier und hier gibts dazu bissl was zu lesen...

    Problem dabei ist, dass sämtliche "atomics" sehr (sehr) zeitaufwendig, und damit langsam ausgeführt werden!
    Um beim Beispiel mit der Schneeballschlacht zu bleiben, wenn eine Million Leute nacheinander werfen müssen, dann dauert das WESENTLICH länger, als wenn alle gleichzeitig werfen!
    Atomic operations sind also das, was man bei parallelem Computing unbedingt vermeiden soll!

    Um es nochmal deutlich zu sagen, OpenCL ist das Werkzeug für massives paralleles Number crunching. Um bissl pillepalle Zählaufgaben wie im Beispiel abzuwickeln, braucht man das wirklich nicht!
    Allerdings ist das ein sehr schönes Beispiel, wie man lokalen Speicher, barriers, und auch atomic operations einsetzen kann. Und die Aufteilung in Teilstücke ^^

    Um die Verwendung von atomics dem Kernel mitzuteilen, benutzt man die #pragma-Anweisung. Genau wie die Verwendung von printf() zur bspw. Debug-Ausgabe direkt aus dem Kernel in die Console! printf() sollte man, sobald der Kernel fertig entwickelt ist, tunlichst wieder entfernen!

    Anbei eine Methode, wie ich für MEINE Devices die optimalen Teilgrößen berechne. Alternativ kann man natürlich auch problemlos beim _CL_RunKernel$DATA_SIZE, 0) statt der Null (OCL legt selbstständig die optimale Workgroupsize fest) die Workgroupsize festlegen.
    Mit den somit herausgefundenen Parametern hat man dann für SEINE Hardware die schnellste Software am Start...

    Spoiler anzeigen
    [autoit]

    #AutoIt3Wrapper_UseX64=n ;

    [/autoit] [autoit][/autoit] [autoit]

    #include <opencl_easy_all.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $KernelSource = _
    "#pragma OPENCL EXTENSION cl_amd_printf : enable " & @CRLF & _;gibts auch für INTEL/NVIDIA, zum debuggen
    "#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable " & @CRLF & _;atomics einschalten
    "__kernel void counter(__global char* input, __constant char* search, __global uint* count, const int iNumElements,const int divisor)" & @CRLF & _
    "{ " & @CRLF & _
    " uint threadid = get_global_id(0)*divisor; " & @CRLF & _;später "Pointer" auf den Anfang der Teilstrings
    " uint i,r; " & @CRLF & _;For/To variablen
    " private uint local_array[16] ; " & @CRLF & _;LOKALES Array , dann muss nicht immer aus dem Globalen Speicher gelesen werden!
    " for (i = 0; i < iNumElements; i++) { " & @CRLF & _;Lokales array nullen....Lokaler Speicher wird nicht initialisiert!
    " local_array[i]=0; " & @CRLF & _
    " } " & @CRLF & _
    " for (r = 0; r < divisor; r++) { " & @CRLF & _;Teilstrings einlesen
    " char data = input[threadid+r]; " & @CRLF & _;einzelnes Zeichen
    " for (i = 0; i < iNumElements; i++) { " & @CRLF & _;ist es Teil des Suchstrings?
    " if (search[i] == data) { " & @CRLF & _
    " local_array[i]+=1; " & @CRLF & _;ja, dann Anzahl im LOKALEN Array erhöhen
    ' //printf("threadid=%s i=%u loc_arr=%u \n",search[i]);//,i,local_array[i]);' & @CRLF & _;nur zum debuggen
    " } " & @CRLF & _
    " } " & @CRLF & _
    " } " & @CRLF & _
    "barrier(CLK_GLOBAL_MEM_FENCE); " & @CRLF & _;warten, bis alle Workitems fertig sind!
    " for (i = 0; i < iNumElements; i++) { " & @CRLF & _;dann Ergenisse vom LOKALEN Speicher in den Globalen schreiben
    ' //printf(" count[i]=%i i=%u loc_arr=%u \n",count[i],i,local_array[i]);' & @CRLF & _
    " atomic_add(&count[i],local_array[i]); // += 1; " & @CRLF & _;
    " } " & @CRLF & _
    "}"

    [/autoit] [autoit][/autoit] [autoit]

    $sInputFile = String(StringToBinary(FileRead(@AutoItExe))) ;Datei einlesen, Größe als Vielfaches von 2^16
    $DATA_SIZE = StringLen($sInputFile)
    $DATA_SIZE = Int($DATA_SIZE / 2 ^ 20) * 2 ^ 20 ;vielfaches von 2, schöner zu teilen^^

    [/autoit] [autoit][/autoit] [autoit]

    $sInputFile = StringLeft($sInputFile, $DATA_SIZE) ;vielfaches von 2
    $aData = "3A7E0F" ;zu suchende Buchstaben testen! "01234567890ABCDEF"
    $Elements = StringLen($aData) ;Anzahl zu suchende Buchstaben

    [/autoit] [autoit][/autoit] [autoit]

    _CL_GetDevice("ALL", 1, 1) ;..oder CPU oder GPU, 1.Var Devicenummer, 2.Var Platform

    [/autoit] [autoit][/autoit] [autoit]

    ;Puffer für das file
    $buffer_data = _dllstructcreate16("char[" & $DATA_SIZE & "]") ;16byte-aligned!
    $CL_buffer_data = _CL_CreateBuffer($buffer_data)
    ;Puffer für den Suchstring
    $buffer_search = _dllstructcreate16("char[" & $Elements & "]")
    $CL_buffer_search = _CL_CreateBuffer($buffer_search)
    ;Puffer für die Rückgabe
    $Buffer_count = _dllstructcreate16("uint[" & $Elements & "]")
    $CL_buffer_count = _CL_CreateBuffer($Buffer_count)

    [/autoit] [autoit][/autoit] [autoit]

    ;Puffer füllen
    DllStructSetData($buffer_data, 1, $sInputFile)
    _CL_WriteBuffer($CL_buffer_data, $buffer_data)

    [/autoit] [autoit][/autoit] [autoit]

    DllStructSetData($buffer_search, 1, $aData)
    _CL_WriteBuffer($CL_buffer_search, $buffer_search)

    [/autoit] [autoit][/autoit] [autoit]

    ;Parameter an den Kernel übergeben
    _CL_SetArg(0, "ptr*", $CL_buffer_data)
    _CL_SetArg(1, "ptr*", $CL_buffer_search)
    _CL_SetArg(2, "ptr*", $CL_buffer_count)
    _CL_SetArg(3, "int*", $Elements)

    [/autoit] [autoit][/autoit] [autoit]

    $min_time = 2 ^ 31 ;kleinste benötigte Kerneltime
    $min_divisor = 0

    [/autoit] [autoit][/autoit] [autoit]

    $CL_DEBUGFLAG = 0 ;Debug-Ausgabe mit 0 ausschalten, um Geschwindigkeit zu erhöhen

    [/autoit] [autoit][/autoit] [autoit]

    For $p = 0 To 16 ;Divisor ermitteln

    [/autoit] [autoit][/autoit] [autoit]

    $divisor = 2 ^ $p
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $divisor = ' & $divisor & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console

    [/autoit] [autoit][/autoit] [autoit]

    For $w = 1 To $Elements ;zählpuffer nullen
    DllStructSetData($Buffer_count, 1, 0, $w)
    Next
    _CL_WriteBuffer($CL_buffer_count, $Buffer_count) ;und Puffer mit Nullen füllen

    [/autoit] [autoit][/autoit] [autoit]

    _CL_SetArg(4, "int*", $divisor) ;Divisor an Kernel übergeben

    [/autoit] [autoit][/autoit] [autoit]

    _CL_RunKernel(Int($DATA_SIZE / $divisor), 0)
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $DATA_SIZE / $divisor = ' & $DATA_SIZE / $divisor & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    $r = profile_cl_event()
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $r = ' & $r & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console

    [/autoit] [autoit][/autoit] [autoit]

    If $r < $min_time Then ;besten Divisor finden
    $min_time = $r
    $min_divisor = $divisor
    MsgBox(262144, Int($min_time) & " ms", "Divisor = " & $min_divisor, 2) ;### Debug MSGBOX
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    _CL_ReadBuffer($CL_buffer_count, $Buffer_count) ;Puffer auslesen

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To $Elements ;und Einzelwerte extrahieren
    $buchstabe = StringMid($aData, $i, 1)
    StringReplace($sInputFile, $buchstabe, $buchstabe, 0, 1) ;AutoIt rulez^^
    $ext = @extended ;anzahl durch AutoIt ersetzter Buchstaben
    $ret = DllStructGetData($Buffer_count, 1, $i) ;Puffer auslesen
    ConsoleWrite($buchstabe & " OCl=" & $ret & " AutoIt=" & $ext & @CRLF) ;und anzeigen
    Next

    [/autoit] [autoit][/autoit] [autoit]

    Next
    ;...das wars schon^^

    [/autoit] [autoit][/autoit] [autoit]

    MsgBox(0, "Testende", "Schnellster Divisor = " & $min_divisor & @CRLF & "mit Teilstringgröße = " & ($DATA_SIZE / $min_divisor) & " dauert " & Int($min_time) & "ms")

    [/autoit] [autoit][/autoit] [autoit][/autoit]
  • Seltsame Events (Fehler) im System

    • Andy
    • 9. November 2014 um 08:22

    Hi,
    habe beim googeln auch nur rausfinden können, dass es sich wohl um "Reste" einer (De-) Installation handelt.
    HIER und HIER bspw.
    Beim Doppelklick auf den Fehler öffnet sich ein Fenster, in dem idR noch weitere Informationen stehen.

  • AutoIt Sysinternal Tools Synchronizer v0.99.6 build 2020-09-23 beta

    • Andy
    • 8. November 2014 um 23:10
    Zitat von AspirinJunkie

    nur halt 100x profaner.

    genau DAS ist angekommen! :thumbup:
    Ich wollte auch nicht UEZ´s Arbeit kritisieren, aber so ist das, wenn man in einem großen EDV-Unternehmen arbeitet, da MUSS man zwangsläufig auf dicke Hose machen :P

  • AutoIt Sysinternal Tools Synchronizer v0.99.6 build 2020-09-23 beta

    • Andy
    • 8. November 2014 um 09:14

    Einzeiler gegen GUI, der Einzeiler gewinnt....
    Wer selektiv Programme aus der Suite benötigt/benutzt, verwendet (wie ich) die Onlineversion.
    Ansonsten habe ich meine WinPE- "Notfall-CD/USB-Stick" in der Tasche mit einer jahrealten Version.

  • OpenCl goes AutoIt Update 31.Dezember 2016

    • Andy
    • 7. November 2014 um 07:34

    Sodele, habe mal deinen Kernel laufen lassen, ich hoffe, dir gehen jetzt Kronleuchter auf^^

    &quot;Script&quot;
    [autoit]

    #AutoIt3Wrapper_UseX64=n

    [/autoit] [autoit][/autoit] [autoit]

    #include <opencl_easy.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $KernelSource = _
    "__kernel void counter(__global char* input, __constant char* search, __global int* count, const unsigned int iNumElements)" & @CRLF & _
    "{" & @CRLF & _
    " uint threadid = get_global_id(0);" & @CRLF & _
    " char data = input[threadid];" & @CRLF & _
    " uint i;" & @CRLF & _
    " for (i = 0; i < iNumElements; i++) {" & @CRLF & _
    " if (search[i] == data) {" & @CRLF & _
    " count[i] += 1;" & @CRLF & _
    " }" & @CRLF & _
    " }" & @CRLF & _
    "}"

    [/autoit] [autoit][/autoit] [autoit]

    $sInputFile = String(StringToBinary(FileRead(@AutoItExe)))
    $DATA_SIZE = StringLen($sInputFile) ;bildgröße=anzahl pixel (rgba)
    $aData = "3A7E0F"
    $Elements = StringLen($adata)

    [/autoit] [autoit][/autoit] [autoit]

    _CL_GetDevice("GPU", 1,1) ;..oder CPU oder GPU, ermittelt das Gerät, auf dem die Berechnungen durchgeführt werden.

    [/autoit] [autoit][/autoit] [autoit]

    ;Puffer für das file
    $buffer_data = _dllstructcreate16("char[" & $DATA_SIZE & "]");16byte-aligned!
    $CL_buffer_data = _CL_CreateBuffer($buffer_data)
    ;Puffer für den Suchstring
    $buffer_search = _dllstructcreate16("char[" & $elements & "]")
    $CL_buffer_search = _CL_CreateBuffer($buffer_search)
    ;Puffer für die Rückgabe
    $Buffer_count = _dllstructcreate16("int[" & $elements & "]")
    $CL_buffer_count = _CL_CreateBuffer($Buffer_count)

    [/autoit] [autoit][/autoit] [autoit]

    ;Puffer füllen
    DllStructSetData($buffer_data, 1, $sInputFile)
    _CL_WriteBuffer($CL_buffer_data, $buffer_data)

    [/autoit] [autoit][/autoit] [autoit]

    DllStructSetData($buffer_search, 1, $aData)
    _CL_WriteBuffer($CL_buffer_search, $buffer_search)

    [/autoit] [autoit][/autoit] [autoit]

    ;Parameter an den Kernel übergeben
    _CL_SetArg(0, "ptr*", $CL_buffer_data)
    _CL_SetArg(1, "ptr*", $CL_buffer_search)
    _CL_SetArg(2, "int*", $CL_buffer_count)
    _CL_SetArg(3, "int*", $Elements)

    [/autoit] [autoit][/autoit] [autoit]

    $CL_DEBUGFLAG = 1 ;Debug-Ausgabe mit 0 ausschalten, um Geschwindigkeit zu erhöhen
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $CL_DEBUGFLAG = ' & $CL_DEBUGFLAG & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console

    [/autoit] [autoit][/autoit] [autoit]

    $t = TimerInit()
    _CL_RunKernel($DATA_SIZE, 0)
    $m = TimerDiff($t)
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $m = ' & $m & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    _CL_ReadBuffer($CL_buffer_count, $Buffer_count)
    $m = TimerDiff($t)
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $m = ' & $m & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To $Elements
    $buchstabe=stringmid($aData,$i,1)
    stringreplace($sInputFile,$Buchstabe,$Buchstabe,0,1) ;AutoIt rulez^^
    $ext = @extended
    $ret = DllStructGetData($Buffer_count, 1, $i)
    ConsoleWrite($Buchstabe & " OCl=" & $ret &" AutoIt="&$ext & @CRLF) ;### Debug Console
    Next

    [/autoit] [autoit][/autoit] [autoit]

    ;...das wars schon^^

    [/autoit]
    &quot;Ergebnisse&quot;
    [autoit]

    verwendetes Device 1;1;4;GPU;BeaverCreek;45838144;1558332692

    [/autoit] [autoit][/autoit] [autoit]

    clEnqueueNDRangeKernel CL_SUCCESS
    @@ Debug(55) : $m = 0.753986456087799
    clEnqueueReadBuffer CL_SUCCESS
    @@ Debug(58) : $m = 28.5525658254356
    3 OCl=7886 AutoIt=95934
    A OCl=7100 AutoIt=40589
    7 OCl=9042 AutoIt=80065
    E OCl=8995 AutoIt=74060
    0 OCl=10088 AutoIt=485313
    F OCl=9419 AutoIt=174165

    [/autoit] [autoit][/autoit] [autoit]

    verwendetes Device 1;2;4;GPU;Caicos;58117512;1585136916

    [/autoit] [autoit][/autoit] [autoit]

    clEnqueueNDRangeKernel CL_SUCCESS
    @@ Debug(55) : $m = 1.01703906807567
    clEnqueueReadBuffer CL_SUCCESS
    @@ Debug(58) : $m = 29.2156928835109
    3 OCl=12268 AutoIt=95934
    A OCl=10193 AutoIt=40589
    7 OCl=13415 AutoIt=80065
    E OCl=13260 AutoIt=74060
    0 OCl=15621 AutoIt=485313
    F OCl=13984 AutoIt=174165

    [/autoit] [autoit][/autoit] [autoit]

    verwendetes Device 1;3;2;CPU;AMD A6-3400M APU with Radeon(tm) HD Graphics;72411976;1558332692

    [/autoit] [autoit][/autoit] [autoit]

    clEnqueueNDRangeKernel CL_SUCCESS
    @@ Debug(55) : $m = 0.69097106714363
    clEnqueueReadBuffer CL_SUCCESS
    @@ Debug(58) : $m = 78.0753341647457
    3 OCl=95424 AutoIt=95934
    A OCl=40521 AutoIt=40589
    7 OCl=79568 AutoIt=80065
    E OCl=73754 AutoIt=74060
    0 OCl=396277 AutoIt=485313
    F OCl=169821 AutoIt=174165

    [/autoit]

    Dein Problem mit den "falschen" Zählergebnissen war natürlich schon bei der Aufgabenstellung klar! Sorry, aber manchmal muss man mit der Brechstange vorgehen 8)
    Dein Kernel macht doch genau, was er soll, es wird ein einzelnes Zeichen aus dem großen String ausgelesen, geschaut, ob es im Suchstring enthalten ist, und dann der Zähler für dieses Zeichen erhöht...

    Ich fange bei der Analyse der Ergebnisse mit der CPU an, die kommen der "richtigen" Ergebnissen schon sehr nahe!
    Stell dir mal eine Schneeballschlacht vor. Du bist eine einzelne Speicherstelle, die bei einem Treffer eine Strichliste führen soll. Dir gegenüber stehen 2 (Dualcore) oder 4(Quadkore) "Kerne", welche dich mit Schneebällen bewerfen. Die Strichliste ist relativ einfach zu führen, denn die 4 "Kerne" müssen ja den Schneeball formen und werfen. Ab und zu sind die Jungs aber geringfügig schneller oder langsamer und mehrere Schneebälle treffen dich GLEICHZEITIG! Da ist es natürlich schwierig für dich die genaue Anzahl der gleichzeitigen Treffer zu zählen, und du machst nur EINEN Strich! Das kommt allerdings nicht oft vor...

    Jetzt spielst du gegen eine GPU mit hunderten, wenn nicht sogar tausenden "Kernen". Alle werfen GLEICHZEITIG mit Schneebällen nach dir und du sollst JEDEN Treffer zählen....unmöglich?! Genau! Das kann niemand, auch die Speicherstelle im Rechner nicht! Capice?!

    DAS ist paralleles Computing!

    Um die "richtige" Trefferanzahl herauszubekommen, musst du jetzt nur noch herausfinden, wie man die "Schneeballwerfer" synchronisiert :D Schönes Wochenende! :thumbup:

  • Wettbewerb (für Anfänger und Fortgeschrittene) ?

    • Andy
    • 6. November 2014 um 22:03

    Ein Schnitt von 28 für 16x16 ist SUPER! Bei den meisten "handgelösten" Rätseln komme ich auf 30-32.

  • OpenCl goes AutoIt Update 31.Dezember 2016

    • Andy
    • 6. November 2014 um 17:47
    Zitat von Techmix

    >Device verfügbar= 1;1;4;GPU;GeForce GTX 460;58662400;57218520
    >Device verfügbar= 1;2;4;GPU;GeForce GTX 460;58662480;57218520
    >Device verfügbar= 2;1;2;CPU;Intel(R) Core(TM) i7 CPU 920 @ 2.67GHz;43780328;43771960

    Ist das die Ausgabe vor oder nach der Neuinstallation? Ist so doch einwandfrei!

    Übrigens hatte ich zufällig letzte Woche einen Rechner zum Neuaufsetzen da, und weil der auch mit Intel-CPU und Nvidia-Graka daherkam, habe ich OpenCl gleich ausprobiert.
    Treiber installiert, läuft.
    Sowohl die "normalen" Beispiele, als auch die Multifunktionen.
    Du musst natürlich aufpassen, dass du die richtigen command_queue[Platform][Device]-Indizes setzt! Wenn vorher 2 Devices(GPUs) auf der "ersten" Platform gesessen haben, und nach dem Installieren dann die CPU "solo", dann stimmen natürlich die Parameter nicht!
    Das hat aber weniger mit OpenCl zu tun, sondern mit deiner Implementation.

    Natürlich könnte man auf dem Standpunkt stehen, eine "Engine" sollte die Last auf alle Devices selbst verteilen können....
    Wie schon weiter oben gesagt, ist Lastverteilung die Sache des Anwenders.
    "Professionelle" Programme machen das übrigens so, dass bei SLI-Verbünden einfach in einen komplett anderen Programmzweig gesprungen wird. D.h. dort gehen die Programmierer den pragmatischen Weg und testen auf Platform1/CPU_oder_SLI und Platform2/CPU_oder_SLI. Problem gelöst^^
    Kannst du übrigens auch so machen, musst nur einen Zweig einbauen für
    _CL_RunKernel_ALL($DATA_SIZE / 2, 0, $comm_queue[1][2]) bzw
    _CL_RunKernel_ALL($DATA_SIZE / 2, 0, $comm_queue[2][2]) je nachdem, ob die GPUs auf Platform 1 oder 2 sitzen

  • Noch ein Oldie

    • Andy
    • 6. November 2014 um 16:55

    Hi auch von einem weitern Oldie^^

    Zitat von Biel

    Beim arbeiten mit dem Editor SciTE muss man zuerst eine Sicherung vornehmen, ehe man mit F5 die Ausführung des Scriptes starten kann

    Nur beim ersten Erstellen eines Scripts, damit ein Dateiname für die (ist die Standardmässig ein- oder ausgeschaltet ? ) Sicherung *.BAK erstellt werden kann.

    Zitat von Biel

    Eine Bildschirmausgabe mit PRINT fehlt, halte ich beim Testen einfacher als MSGBOX

    Schau mal in die EXTRAS, dort vor allem die Debug-Befehle.
    Ich verwende reflexartig alt+d für die Debug-Msgbox und ctrl+shift+d für Debug-Consolewrite. Wirft gleich auch noch die Zeilennummer und den Errorcode aus.

    Btw. kenne ich XPROFAN aus grauen Urzeiten, da ich mir dort die Prospeed.dll mal "ausgeliehen" hatte.

  • Häufigkeit der Wörter in einem Array

    • Andy
    • 6. November 2014 um 07:13

    @DasIch,
    wir vermissen dein Script, in dem du deinen Versuch zur Lösung deines Problems beschreibst!
    Oder soll dir hier jemand das Script fix und fertig vorlegen?

    Btw. gibt es die Funktion _ArrayUnique(), welche 99% deines Problems löst, einige Zeilen umschreiben/ergänzen und das wars...

  • GUICtrlCreateListViewItem ist zu langsam? -> Problem gelöst, aber Warum ist das so?

    • Andy
    • 5. November 2014 um 13:22
    Zitat von Homer J. S.

    Ich denke, du solltest ein extra Skript für die GUI erstellen und ein extra Skript für deine Datenverwaltung und dann lässt du beide Skripte untereinander kommunizieren. Dann sollte dein Speed Problem bezüglich GUI gelöst sein?!


    Offensichtlich hast du das Problem nicht nachvollzogen.
    Das Problem befindet sich in der Darstellung der Liste, also ein reines GUI-Problem. Die Datenverwaltung ist davon völlig losgelöst. Daher besteht auch keine Veranlassung, das Script zu teilen!

    "In grauer Vorzeit", als es noch gar kein Windows gab, hatte man trotzdem schon Listendarstellungen. Da war man so clever und hat ausschliesslich den sichtbaren Teil der Liste ausgelesen und dargestellt. Beim Scrollen wurden einfach die oberen Zeilen "abgeschnitten" und die neuen Zeilen unten angehängt, also immer nur ein kleiner Teil der Liste angezeigt.
    Ich vermute mal, ähnlich funktioniert das heute auch noch, ausser dass in irgendeiner "klickibunti"-Funktion wieder mal mehr Wert auf optischen Schnickschnack (Aero) gelegt wurde, als auf Geschwindigkeit.
    Btw, AERO abschalten lässt einige Programme wesentlich schneller laufen! Leider kein Witz!

  • Radix-Sort mit AutoIt

    • Andy
    • 5. November 2014 um 06:40
    Zitat von AspirinJunkie

    Wenn man die __dRadixUInt() in Assembler umsetzen könnte und in das Skript integrieren kann, dann könnte man vielleicht wirklich eine Sortierungsfunktion erhalten welche in vielen Fällen die _ArraySort schlägt.

    Wird leider so nicht funktionieren, da der Overhead des DllCall() bzw. DllCallAddress() einfach zu groß ist! Einfach gesagt, liegen diese Berechnungen

    Zitat von AspirinJunkie

    in AutoIt für die Standardtypen nativ vor und sind daher verdammt fix.

    8)
    Aber Versuch macht kluch...

    Zitat von AspirinJunkie

    In der Theorie gibt es, vor allem bei großen Datenmengen, genügend Fälle in denen Radixsort dem Quicksort überlegen ist.

    Nicht nur in der Theorie! Da die Zeit für Radixsort linear mit der Menge der zu sortierenden Daten skaliert, ist es schneller. Vorausgesetzt (und das ist der Knackpunkt) die Daten haben eine konstante Schlüssellänge.

    Auch bei Radixsort schlägt die Autoit-Engine wieder erbarmungslos zu, mehr Code = langsamer Code.
    Sobald ein schnellerer Algorithmus mehr Codezeilen benötigt, fällt er hoffnungslos zurück, vgl. div. Verfahren zur Primzahlberechnung hier im Forum

  • Wettbewerb (für Anfänger und Fortgeschrittene) ?

    • Andy
    • 4. November 2014 um 23:27
    Zitat von AspirinJunkie

    Für den Fall, dass es sich um zwei normalverteilte Werte handelt welche verglichen werden sollen, kommt der Zweistichproben-t-Test in Frage.
    Ist deren Standardabweichung nicht gleich (über F-Test ermitteln) nimmt man den Welsh-Test.
    Liegt außerdem keine Normalverteilung vor (z.B. über Shapiro-Wilk-Test testbar), dann weicht man auf nichtparametrische Tests, wie dem U-Test, aus.

    Da hier aber gleich mehrere Stichproben verglichen werden sollen, müsste man wegen des Alpha-Kumulierungsfehlers aber eventuell noch die Anova bzw. den Kruskal-Wallis-Test bei Varianzinhomogenität oder den U-Test als nichtparametrische Alternative, in Betracht ziehen.

    Urgs...
    Ich kaufe ein e und lege einfach fest, dass gefälligst nicht statistisch so lange schöngerechnet werden soll, bis irgendein vorausgesagtes Ergebnis eintritt, sondern dass es einen Satz von Rätseln gibt, welcher von allen Algorithmen gelöst wird. Der Algorithmus mit der niedrigsten Anzahl Züge gewinnt. 8o
    Statistik nur noch für optische Spielereien (Diagramme usw) erforderlich!

  • 1,245 GB AutoIt-Scripte

    • Andy
    • 4. November 2014 um 21:28

    xcopy autoitfolder\*.* nul /E > nul

    für die Ewigkeit!

  • Radix-Sort mit AutoIt

    • Andy
    • 4. November 2014 um 20:59

    Sehr fein umgesetzt!
    Ich hatte RadixSort vor Jahren selbst schon getestet, aber war aufgrund der geringeren Geschwindigkeit im Vergleich zu Quicksort davon abgekommen.
    Wahrscheinlich hatte ich den Algorithmus auch etwas zu kompliziert umgesetzt.
    Für UINT hatte ich das sogar in Assembler, die Buckets waren 0 und 1, sortiert wurde nach den Bits 0 bis 31.
    Insgesamt ein wüstes Speichergeschiebe.

    Wenn man Zahlen in Hex-Darstellung schreibt, kann man sie auch mit einem abgewandelten __dRadixString (0123456789ABCDEF) sortieren. Auch BigINT.
    Mir ist zwar keine Anwendung für sortierte BigINT bekannt, aber das hat ja nichts zu sagen.

  • Kommunikation Skripte untereinander

    • Andy
    • 4. November 2014 um 19:33
    Zitat von rynow

    Genau das versteh ich nicht wie man das machen soll? Wie kann ich weitere Elemente an das DllStructCreate() dranhängen obwohl es bereits erstellt ist?

    Mal angenommen, du hast 1 kB an Speicher reserviert. Deine bisherige Struct ist 200 Byte groß, folglich hast du noch 800 Byte an "Platz" zur Verfügung. Diesen "Platz" kannst du nach Belieben beschreiben. Da du ja beim DllStructCreate() auch einen Pointer angeben kannst, kannst du diesen Bereich innerhalb der 800 Bytes sogar an irgendwelche esoterischen Positionen setzen.

    Weiterhin "überschreibst" du mit einem Dllstructcreate() NICHTS! Gerade im Gegenteil, du erstellst lediglich ein "Fenster" bestimmter Größe, welches du mit Hilfe des Pointers an eine beliebige Position im Speicher setzen kannst.

    Spoiler anzeigen
    [autoit]


    $struct0=dllstructcreate("char[1024]") ;1kB Speicher reservieren, gerne auch per Dll^^

    [/autoit] [autoit][/autoit] [autoit]

    $Struct1 = DllStructCreate("char[36];int;float[5]",dllstructgetptr($struct0)) ;struct

    [/autoit] [autoit][/autoit] [autoit]

    DllStructSetData($Struct1, 1, "Hallo zusammen, ich wünsche euch in ") ;string
    DllStructSetData($Struct1, 2, 875638834) ;int
    DllStructSetData($Struct1, 3, 7.4980148299866E+028, 1) ;float
    DllStructSetData($Struct1, 3, 176357396971520, 2) ;float
    DllStructSetData($Struct1, 3, 1.79819841121566E+028, 3) ;float
    DllStructSetData($Struct1, 3, 7.36467599403446E+031, 4) ;float
    DllStructSetData($Struct1, 3, 1.3673756937187E-019, 5) ;float

    [/autoit] [autoit][/autoit] [autoit]

    ;String "anhängen"
    $struct3 = DllStructCreate("char[28]", DllStructGetPtr($Struct1, 3) + 20);hinter bestehende struct
    DllStructSetData($struct3, 1, " Und einen guten Rutsch! ")

    [/autoit] [autoit][/autoit] [autoit]

    ;gesamter String
    $struct4 = DllStructCreate("char[88]", DllStructGetPtr($Struct1));an Position der bestehenden struct
    MsgBox(0, 0, DllStructGetData($struct4, 1))

    [/autoit] [autoit][/autoit] [autoit]

    $struct5 = DllStructCreate("char[20]", DllStructGetPtr($Struct1, 3))
    MsgBox(0, 0, DllStructGetData($struct5, 1))

    [/autoit] [autoit][/autoit] [autoit]

    $gui = GUICreate("TEST",100,50)
    $label = GUICtrlCreateLabel(" ", 20, 10, 50, 25)
    guisetstate()
    While 1
    $msg = GUIGetMsg()
    If $msg = -3 Then ExitLoop

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 0 To 79
    $struct6 = DllStructCreate("char[8]",dllstructgetptr($struct4)+$i)
    guictrlsetdata($label,dllstructgetdata($struct6,1))
    sleep(100)
    Next
    WEnd

    [/autoit]
  • Kommunikation Skripte untereinander

    • Andy
    • 4. November 2014 um 13:29

    Sieht ja schon gut aus...

    Zitat von rynow

    wie man sowas wie "DllStructAddElement()" realisiert ohne die aktuelle Struct zu zerstören und eine neue mit den Daten anzulegen.

    Du denkst immer noch zu sehr an Arrays. Die Struct ist nichts weiter als ein mit irgendwelchen Daten gefüllter Bereich im RAM. Und wenn du neue Daten anhängen willst, schreib diese Daten doch einfach hinten dran.

    Zitat von rynow

    Aktuell scheitere ich daran Uint zuerkennen, aber ansonsten läuft es ganz gut.

    Wenn es nach mir ginge, gäbe es sowieso nur EINEN anderen Datentyp ausser String, und das wäre DWORD. Damit erschlägst du alle 32-Bit-Datentypen. Der "Empfänger" muss sowieso wissen, welchen Datentyp er aus der Struct ausliest.

  • Kommunikation Skripte untereinander

    • Andy
    • 4. November 2014 um 06:44

    Ja, sehr einfach^^
    Alles eine Sache der Kommunikation.
    Die Dll stellt lediglich die Menge des benutzbaren Speichers zur Verfügung, mit welchen Daten dieser Speicher genutzt wird, bestimmt der Anwender!
    Gerade bei dem Beispiel mit den Strings hatten wir schon die Listen /verketteten Listen angesprochen. Der "Sender" erstellt die Liste, der "Empfänger" klappert nun einfach die Liste so lange ab, bis das Ende erreicht ist.
    Wenn man sich nun ein Format überlegt, nach dem die Datentypen im Speicher abgelegt werden, ist es völlig unerheblich wie viele Daten im Speicher stehen.

    Wenn jetzt übrigens irgendwelche stillen Mitleser meinen, so etwas braucht doch sowieso niemand, sollten diese sich mal überlegen, woher sämtliche Datei- und Speicherdatenformate kommen! Die wachsen nämlich nicht auf Bäumen, sondern werden genau nach dem Prinzip der Weiterentwicklung nach einem bestimmten Bedarf festgelegt!
    Und ob diese "Dateien" nun auf Festplatte oder im Speicher einer Dll stehen, ist unerheblich, man kann sie auch per Mail verschicken und mit jedem anderen Programm/Betriebssystem nutzen!

Spenden

Jeder Euro hilft uns, Euch zu helfen.

Download

AutoIt Tutorial
AutoIt Buch
Onlinehilfe
AutoIt Entwickler
  1. Datenschutzerklärung
  2. Impressum
  3. Shoutbox-Archiv
Community-Software: WoltLab Suite™