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

  • Macro

    • Andy
    • 12. Dezember 2016 um 21:51

    Hi,
    ich versuche, auch in Zusammenarbeit mit externen Programmen, in Excel so viel wie möglich in VBA zu machen.
    Direkt im Excelsheet einige Buttons erstellen, entsprechende Macros schreiben, diese Macros mit den Buttons verknüpfen dauert meist nur einige Minuten.
    Größere Programme/Projekte werden sowieso in VBA realisiert.
    Mit AutoIt werden dann meist nur komplette Steuerungssequenzen für Drittprogramme geschrieben, deren Daten dann aber meist direkt mit Excel weiterver(be)arbeitet.

    Bsp.:
    Excel-VBA-Macro bereitet Daten vor für Drittprogramm und startet AutoIt-Script.
    AutoIt-Script steuert Drittprogramm, dieses schreibt mehrere Dateien. Wenn das AutoIt-Script beendet ist, werden diese Dateien aus Excel per VBA eingelesen und weiterverarbeitet.
    Dabei arbeiten AutoIt und Excel "zusammen", aber gesteuert aus VBA. In AutoIt werden keine Exceltabellen direkt beschrieben.

    Mittlerweile verwende ich Excel-Sheets nur noch als "Daten-Anzeige", Formeln innerhalb der Sheets sind eher selten und wenn, dann werden diese Formeln von Macros in die Zellen geschrieben.
    Gewissermaßen sind die Excel-Sheets nur noch das Frontend für die "Datenbank", in meinem Fall Dateiinhalte, die meist auch von anderen (auch AutoIt-) Programmen genutzt werden.
    Mit würde nie in den Sinn kommen per AutoIt eine (idR sowieso offene) Exceltabelle zu bearbeiten, wenn ich diese Tabelle mit einem Mausklick auf einen Button direkt per Excelmacro bearbeiten kann. Wieso auch?
    In Excel befinden sich sämtliche Features, um Daten optimal visuell aufzubereiten und darzustellen. Diese Features können idR sowieso nur sehr schwer aus AutoIt angesprochen werden. Mir würde sich die Frage stellen, wie ich aus einer geöffneten Exceltabelle ein AutoItscript starten soll, welches dann diese Tabelle (und ggf. andere Tabellen/Sheets) bearbeitet?
    Ich wundere mich oft, wie häufig die vom geschätzten Kollegen Water erstellte Excel-UDF "misbraucht" wird, weil der "Programmierer" einfachste Excel-Macros nicht gebacken bekommt. Wobei der Excel-Macrorecorder bestimmt nicht ultimativ ist, so liefert er zumindest ein gutes "Grundgerüst" ab, welches man einfachst erweitern kann.

  • Update autoit.de Forum

    • Andy
    • 11. Dezember 2016 um 12:35
    Zitat von autoiter

    da bleibt noch der Gedanke von bazii. Wenn das stimmt, würde man sich später womöglich Probleme einhandeln, die vermeidbar gewesen wären.
    Wie schätzt du das denn ein admin ?

    Nochmal, ES GIBT ZZT. KEINEN GRUND FÜR EIN UPDATE!
    Es gibt nichtmal problemlos lauffähige Versionen, jedenfalls habe ICH noch keine gefunden. Zur Zeit sind Demos im Umlauf und diese werden auch getestet, real in Projekte umgesetzte Produktivversionen habe ich (!) keine gefunden! Im Hintergrund wird seitens Entwickler fleissig gebugfixt und gestrickt...
    Stattdessen wird in den meisten Forenbeiträgen empfohlen, mit dem Umstieg abzuwarten...
    Ggf. gibt es eine Linksammlung von PRODUKTIV genutzten Websites (vergleichbar mit unseren Forum) welche auf dieser "neuen" Version aufsitzen?

    Und es geht auch nicht PRIMÄR um Sicherheitsupdates, sondern um eine völlig neue Software! Und mit der handeln wir uns mehr Ärger ein, als wir gebrauchen können! Wer wird denn administrativ die notwendigerweise nötigen Stunden/Tage/Wochen/Monate an Arbeit investieren (müssen), um es unseren(!) Usern und deren Ansprüchen Recht zu machen?
    Beim letzten Umstieg auf die aktuelle Forensoftware haben wir schon Federn lassen müssen, und das TROTZ der vielen hineingesteckten Arbeit der Helfer! Danke nochmal dafür!

    //EDIT

    Interssanterweise betreibt Woltlab sein eigenes Community-Forum noch mit der "alten" Version.... das hat mit Sicherheit Gründe!

  • Update autoit.de Forum

    • Andy
    • 11. Dezember 2016 um 11:50
    Zitat von Oscar

    Allerdings habe ich auch (wie Andy) so Bedenken, ob es dieses Mal reibungslos ablaufen wird.
    Gibt es denn eine Auflistung, was sich da alles getan hat (neue Funktionen, Bugfixes, etc.)?

    Zitat von chip

    Ja gibt es, nicht wundern dass da was von Suite 3 steht. Im Zuge der neuen Version wurde die Benamung geändert community.woltlab.com/thread/2…ltlab-suite-3-0/?pageNo=1

    Ich habe aus chip´s Link die ersten 3 und letzten 5 Seiten des Threads gelesen, und hatte ein deja vu....GENAU so ein Gelaber seitens Entwickler und Fanboy´s gab´s dort auch schon beim letzten "Update". Erschreckend vor allem, dass KEINER der dort schreibenden "Fachleute" eine zwingende Notwendigkeit für dieses Update sieht.
    Nach google-Suche zu diesem Thema in anderen Foren dort vergleichbares...

    Das sieht für mich eher so aus, als ob Herstellerseitig krampfhaft auf den social-media-Hype für Forensoftware aufgesprungen werden muss. Ob wir so etwas hier bei uns überhaupt benötigen, ist fraglich/diskussionswürdig.
    Mir drängen sich sofort Vergleiche auf zu Windows XP, da wurde regelrecht Angst geschürt, ob "nicht mehr unterstützter Sicherheit". Fakt ist definitiv, das JEDE neue Software mehr Bugs/Fehler/Einfalltore hat, wie eine 14 Jahre alte, "zugenagelte" und abgesicherte Installation. Ich nutze übrigens auf einigen Rechnern immer noch problemlos XP und hatte neulich das Problem, eine Win98-Software für eine Uralt-Maschinensteuerung bereitstellen zu müssen. Da war das Problem, die passende HARDWARE(!) incl. aller erforderlichen Schnittstellen aufzutreiben. Glücklicherweise wurde noch ein 18 Jahre alter "Laptop" aufgetrieben, der nach 12 Jahren im Kellerregal anstandslos anlief, sich mit dem Netzwerk (auch Internet) verband und seine Arbeit klaglos verrichtete. Und, oh Wunder, selbst nach ausgedehnten "Surfsessions" im Internet per ebenfalls "uralten" Opera- und Firefox-Browsern (die wurden vorsichtshalber NICHT geupdatet!) ist der Rechner nicht vor Viren übergelaufen und wurde auch nicht augenblicklich in ein Botnetz integriert....

    Selbstverständlich sollte eine Forensoftware sicherheitstechnisch auf dem neuesten Stand gehalten werden. Das heisst aber nichts anderes, als das BEKANNTE Einfallstore schnellstmöglich geschlossen werden müssen. DAFÜR sind Sicherheitsupdates da. Mir zumindest ist KEIN EINZIGES Sicherheitsupdate bekannt, dass "vorsorglich" eingespielt wird/wurde. Zuerst wird die Lücke ausgenutzt/gefunden, der Sicherheitsexperte schreibt den Bugfix und DER wird dann eingespielt. Wie soll das auch anders sein, das würde ja heißen, dass Lücken "absichtlich/versehentlich" in Software integriert werden, nur um aus Entwicklerseite fleissig "Sicherheitsupdates" nachschiessen zu können. :/

    Daher meine Meinung: "Ruhe bewahren!"
    Unser Forum wird nicht von Heute auf Morgen zu einem sicherheitstechnischen Problem! Und auch die Usability bleibt gleich, ob das bei der "neuen" Forenversion auch so bleibt, würde ich abwarten!

  • Update autoit.de Forum

    • Andy
    • 10. Dezember 2016 um 19:50

    @Bitnugger, auf der Startseite rechts zwischen "Team" und "Downloads" :D
    Mit 3 Klicks war die Spende erledigt... :thumbup:

  • Update autoit.de Forum

    • Andy
    • 10. Dezember 2016 um 19:45

    Hi,
    wird es im Falle eines Updates wieder zu den schon beim letzten Update festgestellten Einschränkungen/Fehlern/Unzulänglichkeiten kommen?
    "Damals" hat es ja schon viele Stunden/Tage/Wochen Arbeit im Hintergrund gekostet, damit der Forenbetrieb auch wenigstens halbwegs aufrecht erhalten werden konnte! An alle daran Beteiligten nochmals vielen Dank!!!
    Von den verlorenen Beiträgen und bis heute toten Links möchte ich aber nicht anfangen...

    Ggf. sollte man erst einmal andere Forenbetreiber fragen, wie dort das Update abgelaufen ist. Imho herrscht hier bei uns zzt keine Not, inwieweit das Update überhaupt sicherheitsrelevant ist, bleibt abzuwarten!

  • Assemblercode - Noch optimierbar?

    • Andy
    • 9. Dezember 2016 um 22:48

    Tja, irgendwann musste es mal soweit kommen....
    Andy programmiert C :Face:

    Aber wenn schon, denn schon 8o
    Anbei die nach C portierte ASM-Version (wer kann DAS von sich behaupten, als Anfänger hingedröselt zu haben :party: ) mit 4 SSE/SIMD-Schleifenbefehlen, natürlich skalar, d.h. die 128-Bit-Register werden in 2x double (64Bit) aufgeteilt und dann wird jeweils der 1/positiv und 1/negativ zusammengezählt (die erg-variable) und positiv++4 und negativ--4 berechnet, und die Schleife braucht gegenüber der "einfachen" Version nur noch halb so lange...

    //edit2 Quellcode "schön" gemacht^^

    C
    #include <sys/time.h>
    #include <stdio.h>
    #include <emmintrin.h>
    //#include <xmmintrin.h>
    #define LOOPSEACH 10000000
    double ret[2] __attribute__((aligned(16)));
    
    
    int main (void){
    		struct timeval tim;
        gettimeofday(&tim, NULL);
        __m128d a = {1.0L, 1.0L};  //  1/x
        __m128d b = {4.0L, -4.0L}; //  positive nenner +4 , negative nenner -4
        __m128d c = {1.0L, -3.0L}; // 
    	__m128d d; // Zwischenspeicher
        __m128d erg = {0.0L, 0.0L}; //ergebnis = summe aus 1/c
    	 for(int i = 0; i < LOOPSEACH/2; i++) {
    		d = a;            //immer 1.0 1.0
    		d = d / c;        //_mm_div_pd(d,c);     // 1/c1   1/-c2
    		c = c + b;        //_mm_add_pd(c,b);     // c1=c1+4   c2=c2-4		
    		erg = erg+d;      //_mm_add_pd(erg,d); // erg = erg + (1/c1 + 1/-c2)
    	 }
    	_mm_store_pd(ret,erg);
    	printf("ret1= %.12f  ret2= %.12f   summe= %.14f \n" ,ret[0],ret[1],(ret[0]+ret[1])*4); 
    	struct timeval tim2;
        gettimeofday(&tim2, NULL);
        printf("Duration mSec %f\n", (float)((tim2.tv_sec-tim.tv_sec)*1000.0) + ((tim2.tv_usec-tim.tv_usec)/1000.0) );
        return 0;
    }
    Alles anzeigen

    Laufzeit: auf die Millisekunde so schnell wie mein ASM-Code :klatschen: wzbw 8)

    //EDIT
    bissl im code rumgespielt und festgestellt, die "einfachen" Operatoren funktionieren mit den _m128d Variablen auch! Die Schleife wird also zu

    Code
    for(int i = 0; i < LOOPSEACH/2; i++) {
    		d = a;            //immer 1.0 1.0
    		d = d / c;        //_mm_div_pd(d,c);     // 1/c1   1/-c2
    		c = c + b;        //_mm_add_pd(c,b);     // c1=c1+4   c2=c2-4		
    		erg = erg+d;      //_mm_add_pd(erg,d); // erg = erg + (1/c1 + 1/-c2)
    	 }

    //EDIT3
    der vom Compiler erstellte Schleifenblock...FEEEETTTT!!!

  • Assemblercode - Noch optimierbar?

    • Andy
    • 9. Dezember 2016 um 13:06

    chesstiger,

    Zitat von chesstiger

    Kompiliert habe ich es unter Debian 8 mit gcc, da Windows aber ebenfalls POSIX-Threads unterstützt, sollte sich das auch mit VC++ oder so für Windows kompilieren lassen.

    hat mich jetzt 4 Stunden gekostet, deinen Code lauffähig zu bekommen :D
    Ich verwende MINGW Developer Studio (die neueste Version ist von 2008), welches ich per MINGW-GET-SETUP auf die neueste MINGW-Version geupdatet habe.
    Danach folgte per MINGW Installation Manager die Installation des mingw-libthreadgc (NICHT libthreadgce !!!) - paketes.

    Nach 2 hieben auf F8 (Build and execute) wurde dein Code anstandslos compiliert, allerdings meckerte die EXE, dass sie nicht lauffähig ist, da die Datei pthreadgc-3.dll fehlt. Diese Datei aus den Tiefen des MINGW in das Verzeichnis der EXE kopiert und alles lief....Die DLL stellt die POSIX-Kompatibilität zur Windows-API bereit, also die "Windows-API Thread Funktionen"

    Jetzt versuche ich mal, inwieweit ich das hinbekomme, Zeiten ausgeben zu lassen, denn das ist ja das interessante dabei 8o
    ....to be continued

    //EDIT1
    oha, schon nach einigen Sekunden habe ich es als C-Anfänger hinbekommen, die Laufzeit zu ermitteln....schön, wenn man bereits aus alten Projekten die Zeilen kopieren kann :rolleyes:

    Der erzeugte C-Code ist imho sauschnell! Mein ASM-Code ist gerade mal doppelt so schnell, was daran liegt, dass zwar die EXAKTEN SSE-Befehle verwendet werden wie in meinem Code, aber nicht skalar, d.h. der Compiler ist nicht in der Lage, die vorhandene Registerbreite von 2 doubles voll auszunutzen, es wird nur eines benutzt....
    Aber da werde ich mich dahinterklemmen, imho habe ich etwas darüber gelesen.
    float2, float3 und float4 (und andere) Datentypen gibt es ja, ggf auch ein double2?! Dann könnte der Compiler die Register "richtig" füttern und der erzeugte Code wäre in etwa so schnell wie der ASM-Code!

    Das macht übrigens der Compiler aus dem loop:
    asm_pi.JPG

  • Hilfe bei Scannereingabe in ein Textfeld

    • Andy
    • 8. Dezember 2016 um 21:46
    Zitat von Zeitriss

    Local $iInput = Number(GUICtrlRead($hI_ETI))

    Naja, mal wieder ein Versuch....
    Wie so nicht einfach RICHTIG den Scanner abfragen und den gesendeten Code mittels Binary untersuchen?! Dann werden jedenfalls sämtliche gesendeten Zeichen angezeigt, incl. der nicht darstell(umwandel)baren! Je nach Tastaturemulation können beim Scannen diverse Zeichen mitgeschickt werden, das erlaubt u.a. auch die Erkennung/Unterscheidung, ob eine Tastatur oder ein Scanner angeschlossen/bedient wurden.

  • _IsPressed in einer Schleife bei vielen Tasten langsam

    • Andy
    • 8. Dezember 2016 um 21:38

    Hi,
    _ispressed() ist wieder mal so eine Schwachsinnsfunktion, die niemand wirklich braucht!
    In jedem Uralt-Basic und in jeder anderen vernünftigen Programmiersprache gibts einen inkey-Befehl, welcher einfach die gedrückte Taste bzw. den Tastaturcode zurück gibt!
    Aber da die AutoIt-Dev´s ja eher Angst vor Scriptkiddies mit Keylogger-Ambitionen haben, statt Tastaturabfragen ordentlich zu bearbeiten, bleibt wieder mal nichts weiter übrig, als die üblichen API-funktionen zu bemühen....
    Das kann man so machen

    AutoIt
    Global $__inkey_flag=false
    Global $__Tasta_code[256][2], $hDLL = DllOpen("user32.dll")
    
    
    
    
    $hgui = GUICreate("Tasten...", 400, 200)
    GUISetState()
    
    
    $label1 = GUICtrlCreateLabel("", 10, 10, 300, 30)
    $label2 = GUICtrlCreateLabel("", 10, 40, 300, 30)
    $label3 = GUICtrlCreateLabel("", 10, 70, 300, 30)
    
    
    GUICtrlSetData($label1, "Bitte Tasten (auch gleichzeitig) drücken")
    
    
    While GUIGetMsg() <> -3
        $a = _inkey()                                 ;Tastenanzeige
        GUICtrlSetData($label2, "Taste(n) : " & $a)
        $a = _inkey(1)                                ;hexcodes
        GUICtrlSetData($label3, "Hexcodes : " & $a)
    WEnd
    
    
    
    
    
    
    Func _inkey($flag = 0)                            ;gibt die gleichzeitig gedrückten Tasten zurück, wenn flag=1 gibt dann tastaturcode zurück
    
    
        If $__inkey_flag = False Then                 ;first run
            $__inkey_flag = True
            $tastacode = "01 Left mouse button,02 Right mouse button,04 Middle mouse button (three-button mouse),05 Windows 2000/XP: X1 mouse button,06 Windows 2000/XP: X2 mouse button,08 BACKSPACE,09 TAB,0C CLEAR,0D ENTER,10 SHIFT,11 CTRL,12 ALT,13 PAUSE,14 CAPS LOCK,1B ESC,20 SPACEBAR,21 PAGE UP,22 PAGE DOWN,23 END,24 HOME,25 LEFT ARROW,26 UP ARROW,27 RIGHT ARROW,28 DOWN ARROW,29 SELECT,2A PRINT,2B EXECUTE,2C PRINT SCREEN,2D INS,2E DEL,30 0,31 1,32 2,33 3,34 4,35 5,36 6,37 7,38 8,39 9,41 A,42 B,43 C,44 D,45 E,46 F,47 G,48 H,49 I,4A J,4B K,4C L,4D M,4E N,4F O,50 P,51 Q,52 R,53 S,54 T,55 U,56 V,57 W,58 X,59 Y,5A Z,5B Left Windows,5C Right Windows,60 Numeric pad 0,61 Numeric pad 1,62 Numeric pad 2,63 Numeric pad 3,64 Numeric pad 4,65 Numeric pad 5,66 Numeric pad 6,67 Numeric pad 7,68 Numeric pad 8,69 Numeric pad 9,6A Multiply,6B Add,6C Separator,6D Subtract,6E Decimal,6F Divide,70 F1,71 F2,72 F3,73 F4,74 F5,75 F6,76 F7,77 F8,78 F9,79 F10,7A F11,7B F12,7C-7F F13  - F16,80H-87H F17  - F24,90 NUM LOCK,91 SCROLL LOCK,A0 Left SHIFT,A1 Right SHIFT,A2 Left CONTROL,A3 Right CONTROL,A4 Left MENU,A5 Right MENU,BA ;,BB =,BC ,,BD -,BE .,BF /,C0 `,DB [,DC \,DD ]"
            $a = StringSplit($tastacode, ",", 1)      ;string am komma splitten
    
    
            For $i = 1 To UBound($a) - 1              ;$tastacodes in Array
                $__Tasta_code[Dec(StringLeft($a[$i], 2))][1] = StringTrimLeft($a[$i], 3)
            Next
        EndIf
    
    
        $string = ""                                  ;gedrückte Tasten
        For $i = 1 To 254                             ;eigentlich nur bis 221
          $key = DllCall($hDLL, "short", "GetAsyncKeyState", "int", $i)
    
    
            If BitAND($key[0], 0x8000) Then           ;MSB gesetzt
                If $flag Then
                    $string &= "0x" & Hex($i, 2) & "+"
                Else
                    If $__Tasta_code[$i][1] = "" Then $__Tasta_code[$i][1] = "unknown  code=0x" & Hex($i, 2) & " ";falls Tastencode unbekannt
                    $string &= $__Tasta_code[$i][1] & "+"
                EndIf
            EndIf
        Next
        $string = StringTrimRight($string, 1)         ;+ am Ende entfernen
        Return $string                                ;string zurückgeben
    
    
    EndFunc                                           ;==>_inkey
    Alles anzeigen

    oder so

    AutoIt
    $hGui = GUICreate("Example 1 - Press any key to exit...", 400, 100)
    GUISetState()
    $sKeyboardState = _WinAPI_GetKeyboardState(1)
    While _WinAPI_GetKeyboardState(1) = $sKeyboardState
        Sleep(100)
    WEnd
    GUIDelete($hGui)
    
    
    Sleep(500)
    
    
    $hGui = GUICreate('Example 2 - Press "A" to exit...', 400, 200)
    GUISetState()
    $aKeyboardStateOld = _WinAPI_GetKeyboardState()
    While 1
        $aKeyboardState = _WinAPI_GetKeyboardState()
        If $aKeyboardState[65] <> $aKeyboardStateOld[65] Then ExitLoop
        Sleep(100)
    WEnd
    GUIDelete($hGui)
    
    
    Sleep(500)
    
    
    $hGui = GUICreate('Example 3 - Type...', 400, @DesktopHeight - 100)
    $hLabel = GUICtrlCreateLabel("", 2, 2, 396, @DesktopHeight - 104)
    GUISetState()
    While GUIGetMsg() <> -3
        $aKeyboardState = _WinAPI_GetKeyboardState()
        $sKeys = "I" & @TAB & "CHR" & @TAB & "State" & @TAB & "Toogle" & @LF
        For $i = 10 To 90
            $sKeys &= $i & @TAB & Chr($i) & @TAB & BitAND($aKeyboardState[$i], 0xF0) & @TAB & BitAND($aKeyboardState[$i], 0x0F) & @LF
        Next
        GUICtrlSetData($hLabel, $sKeys)
        Sleep(100)
    WEnd
    
    
    
    
    ; #FUNCTION# ====================================================================================================================
    ; Name...........:     _WinAPI_GetKeyboardState
    ; Description ...:     Returns the status of the 256 virtual keys
    ; Syntax.........:     _WinAPI_GetKeyboardState($iFlag=0)
    ; Parameters ....:     $iFlag   - Return Type
    ;                      0 Returns an array[256]
    ;                    1 Returns a string
    ; Return values .:     Success  - Array[256] or String containing status of 256 virtual keys
    ;                      Failure  - False
    ; Author ........:     Eukalyptus
    ; Modified.......:
    ; Remarks .......:     If the high-order bit is 1, the key is down; otherwise, it is up.
    ;                    If the key is a toggle key, for example CAPS LOCK, then the low-order bit is 1
    ;                    when the key is toggled and is 0 if the key is untoggled
    ; Related .......:     _IsPressed
    ; Link ..........;
    ; Example .......;
    ; ===============================================================================================================================
    Func _WinAPI_GetKeyboardState($iFlag = 0)
        Local $aDllRet, $lpKeyState = DllStructCreate("byte[256]")
        $aDllRet = DllCall("User32.dll", "int", "GetKeyboardState", "ptr", DllStructGetPtr($lpKeyState))
        If @error Then Return SetError(@error, 0, 0)
        If $aDllRet[0] = 0 Then
            Return SetError(1, 0, 0)
        Else
            Switch $iFlag
                Case 0
                    Local $aReturn[256]
                    For $i = 1 To 256
                        $aReturn[$i - 1] = DllStructGetData($lpKeyState, 1, $i)
                    Next
                    Return $aReturn
                Case Else
                    Return DllStructGetData($lpKeyState, 1)
            EndSwitch
        EndIf
    EndFunc   ;==>_WinAPI_GetKeyboardState
    Alles anzeigen

    oder so

    AutoIt
    #include <WinAPI.au3>
    #include <WindowsConstants.au3>
    #include <StructureConstants.au3>
    
    
    OnAutoItExitRegister('OnAutoItExit')
    
    
    Global $hmod, $hHook, $hStub_KeyProc, $buffer = '',$scannerbufferflag=0
    
    
    $hStub_KeyProc = DllCallbackRegister('_KeyProc', 'long', 'int;wparam;lparam')
    $hmod = _WinAPI_GetModuleHandle(0)
    $hHook = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, DllCallbackGetPtr($hStub_KeyProc), $hmod)
    While Sleep(100)
    WEnd
    
    
    Func _EvaluateKey($keycode)
    	consolewrite ($keycode&@crlf)
    	Switch $keycode
    
    
    		case asc("~")  ;tilde als startzeichen
    			$scannerbufferflag=1  ;nur scannereingaben aufzeichnen
    			Tooltip("Scancode start!")
    		Case 48 To 57 ; 0 - 9
    			ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $buffer = ' & chr($keycode) & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    			if $scannerbufferflag=1 then
    				$buffer &= Chr($keycode)
    				tooltip ("Scanner sendet: "&$buffer)
    			endif
    		Case 13 ; RETURN
    
    
    			if $scannerbufferflag=1 then
    
    
    				Tooltip("Scanner hat gesendet: " & $buffer)
    			Endif
    			$buffer = ''
    			$scannerbufferflag=0
    		Case 27 ; ESC
    			Exit
    		Case Else
    			$buffer = ''
    	EndSwitch
    EndFunc   ;==>_EvaluateKey
    
    
    Func _KeyProc($nCode, $wParam, $lParam)
    	Local $tKEYHOOKS = DllStructCreate($tagKBDLLHOOKSTRUCT, $lParam)
    	If $nCode < 0 Then Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
    	If $wParam = $WM_KEYDOWN Then _EvaluateKey(DllStructGetData($tKEYHOOKS, 'vkCode'))
    	Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
    EndFunc   ;==>_KeyProc
    
    
    Func OnAutoItExit()
    	_WinAPI_UnhookWindowsHookEx($hHook)
    	DllCallbackFree($hStub_KeyProc)
    EndFunc   ;==>OnAutoItExit
    Alles anzeigen


    oder so

    Tastatur für Bildschirm

  • AuPDF - PDF Dateien direkt aus AutoIt erstellen

    • Andy
    • 8. Dezember 2016 um 19:22

    Hi tigerpapers,
    der letzte Besuch des Users "Ahnungslos" in diesem Forum ist ca. ein Jahr her, der letzte Beitrag in diesem Thread ist zwei Jahre alt....
    Was erwartest du?

    Versuche, die UDF selbst umzustricken, und wenn etwas dabei nicht klappt, erstelle einen passenden Thread mit dem was du bereits gemacht hast!

  • _GDIPlus_ImageCalcDif

    • Andy
    • 8. Dezember 2016 um 18:16

    Ich empfehle für SSE das hier: http://lars.nocrew.org/computers/processors/x86-64/26568.pdf

    "Richtig" in einem PDF-Viewer angezeigt, sucht man links die Befehle durch, welche mit Erklärung und DARSTELLUNG ALS BILD (wieso bekommt INTEL so etwas nicht hin?) rechts dargestellt werden!Zwischenablage01.jpg

    Der ASM-Code in Scite läuft automatisch mit dem Debugger mit, d.h. Scite springt zum nächsten _asmdbg_(), sobald der "Next"-Button im Debuggerfenster angeklickt wird.

    Dateien

    Zwischenablage02.JPG 219,26 kB – 0 Downloads
  • _GDIPlus_ImageCalcDif

    • Andy
    • 8. Dezember 2016 um 13:30
    Zitat von Mars

    Und ich hatte schon Angst vor deinem Kommentar, weil ich kein SSE benutzt habe

    DAS hebe ich mir für später auf! 8o

    Egal, hauptsache es funktioniert! :thumbup:
    Obwohl SSE gerade bei den 4x32Bit (oder besser 16x8Bit) -Befehlen vieles an Arbeit sparen würde! Du könntest 4 Pixel laden, und mit einem Befehl 16 Bytes bearbeiten.
    Da lob ich mir den "neuen" AssembleIt-Debugger, der stellt die Registerinhalte sehr schön dar.

  • _GDIPlus_ImageCalcDif

    • Andy
    • 7. Dezember 2016 um 19:29

    Einwandfrei! :thumbup:
    Daraus könnte man bestimmt ein feines "Finde doppelte Bilder"-Programm/Script basteln 8o

  • Assemblercode - Noch optimierbar?

    • Andy
    • 7. Dezember 2016 um 07:16

    Ich vermute, bei einem Quadcore-Prozessor (ggf auch Dual-Core mit HT) liegt die Grenze bei 3 Threads, weil Windows sich immer einen Thread "reserviert", um das System laufen zu lassen. Sicher wird es auch trotzdem "Core-Hopping" geben, das müsste man mal genauer profilen. Aber Faktor 3 ist definitiv eine Hausnummer!

    Für eine Compilersprache ist die Optimierung per Multithreading ziemlich einfach, Schalter setzen, fettich!


    Zitat von UEZ

    Ich habe mal den FB Code als x64 laufen lassen -> Resultat siehe oben Post#31.

    Bei einem Thread die Laufzeit mehr als halbiert!

    Naja, das demonstriert nur, wie "langsam" der erzeugte 32Bit-Code ist, obwohl, wenn SSE eingeschaltet, der SSE-Code in 32Bit genauso schnell läuft wie im 64Bit-Modus! Für die SSE-Befehle bleibt die Laufzeit in beiden Modi ja gleich!
    Wenn man anfängt zu "handoptimieren", wird der Abstand zum vom Compiler erstellten Code immer größer. Es macht also in einer Compilersprache Sinn, die Funktionsweise des Compilers wenigstens zu kennen und zu wissen, an welchem "Rädchen" man drehen muss, um dessen Code schneller laufen zu lassen.
    Wenn man sich jetzt noch verdeutlicht, wie viel schneller der Code wäre, wenn (wie schon weiter oben erwähnt) AVX/FMA verwendet wird, dann ist auch klar, warum auch der Abstand von "Profi-Compilern" und dessen Einsatz auf den neuesten Prozessoren zum "Otto-Normalo-F5-Drücker" mit seinem 200-€-Prozessor immer größer wird (werden muss).

  • Assemblercode - Noch optimierbar?

    • Andy
    • 6. Dezember 2016 um 23:39

    Wieder mal sehr interessant die unterschiedlichen Ergebnisse, obwohl ich für eine "schöne" Darstellung die letzten 3 Nachkommastellen schon abgeschnitten hatte. Ggf. habe ich ja Lust, die entsprechenden Bits (wie hier http://www.plantation-productions.com/Webster/www.ar…Arithmetic.html beschrieben gibts das auch für SSE/SIMD) zu setzen.... ||

  • Libre Office SaveAs Frage

    • Andy
    • 6. Dezember 2016 um 23:13

    Funktionssammlung OpenOffice Calc hier habe ich einige OO-Funktionen erstellt, damit arbeite ich heute noch (das Script ist 6 Jahre alt und läuft mit der aktuellen OO-Calc-Version einwandfrei)

    Es läuft eine kleine Demo ab, was die Funktionen alles können, u.a. auch Export in diversen Formaten:

    AutoIt
    ;speichern in verschiedenen Formaten
    _OOStoreBook($file & ".ods") ;speichern im OOcalc-format
    _OOStoreBook($file & ".xls", "MS Excel 97")
    _OOStoreBook($file & ".pdf", "calc_pdf_Export")
    _OOStoreBook($file & ".txt", "Text - txt - csv (StarCalc)")
    _OOStoreBook($file & ".html", "HTML (StarCalc)")
    _OOCloseBook()
  • Assemblercode - Noch optimierbar?

    • Andy
    • 6. Dezember 2016 um 22:46

    Sodele, das ist imho das Ende der Fahnenstange...Multithreading in AutoIt 8o

    Ich lasse einfach Threads von 1 bis 24 laufen, ist natürlich Quatsch, idR sollte "Otto-Normalo-PC-User" Quad-, Hex-, oder Octa-Cores haben.
    Bei mir zumindest bringen viele Threads nichts, ist auch klar, der Overhead frisst irgendwann den Gewinn völlig auf...aber spielt selbst mal rum.

    Für meinen Laptop-Quadcore AMD @2.3Ghz:
    Ich habe 1000000000 Durchläufe eingestellt, da bekomme ich folgendes Ergebnis für die ersten 10 Threads

    Spoiler anzeigen

    Threads: 1 Time: 3814.4ms PI: 3.141592652586
    Threads: 2 Time: 1959.2ms PI: 3.141592652591
    Threads: 3 Time: 1426.5ms PI: 3.141592652598
    Threads: 4 Time: 1517.9ms PI: 3.141592652593
    Threads: 5 Time: 1221.8ms PI: 3.141592652591
    Threads: 6 Time: 1201.7ms PI: 3.141592652588
    Threads: 7 Time: 1138.5ms PI: 3.141592652589
    Threads: 8 Time: 1073.5ms PI: 3.141592652586
    Threads: 9 Time: 1047.2ms PI: 3.141592652587
    Threads: 10 Time: 1093.9ms PI: 3.141592652590


    Bei den aus dem Startpost vorgegebenen 10000000 Durchläufen erhalte ich

    Spoiler anzeigen

    Threads: 1 Time: 41.0ms PI: 3.141592553586
    Threads: 2 Time: 21.4ms PI: 3.141592553591
    Threads: 3 Time: 13.4ms PI: 3.141592553590
    Threads: 4 Time: 20.8ms PI: 3.141592553589
    Threads: 5 Time: 16.8ms PI: 3.141592553590
    Threads: 6 Time: 22.3ms PI: 3.141592553590
    Threads: 7 Time: 19.6ms PI: 3.141592553589
    Threads: 8 Time: 16.4ms PI: 3.141592553590
    Threads: 9 Time: 17.9ms PI: 3.141592553589
    Threads: 10 Time: 22.2ms PI: 3.141592553590


    was man feststellen kann ist maximal ein Faktor 3 an Geschwindigkeit durch Multithreading! Aber auch nicht schlecht....

    OpenCL anyone? :rock:

    AutoIt
    ;aligncomment=50
    ;~ #include <assembleit2_64.au3>
    
    
    #AutoIt3Wrapper_UseX64=n
    
    
    
    
    #cs Pi_Leibnitz
        Use32                                          ;32Bit!
    
    
        mov eax,[esp+4]                                ;pointer auf die param[$i]-struct
        mov esi,eax                                    ;sichern
    
    
        mov ecx,[esi]                                  ;n
        mov ebx,[esi+4]                                ;Startpos
        mov edx,[esi+8]                                ;Step
    
    
        shr ecx,1                                      ;n/2 es werden pro schleifendurchgang das positive und negative aufsummiert
    
    
        xorpd xmm4,xmm4                                ;0.0 _ 0.0 die summe dieser beiden wird PI/4
    
    
        mov eax,4
        movd xmm6,eax
        pshufd xmm6, xmm6, 0xE0
        CVTDQ2PD xmm6, xmm6                            ;4.0 _ -4.0
    
    
        mov eax,1
        movd xmm0,eax
        pshufd xmm0, xmm0, 0xE0                        ;1   _ 1
        CVTDQ2PD xmm0, xmm0                            ;1.0 _ 1.0
        ;~      _asmdbg_()
        neg edx                                        ;step
        mov eax,edx
        movd xmm1,eax
        CVTDQ2PD xmm1, xmm1                            ;0.0 _ -4.0
        neg edx                                        ;4
        movd xmm2,edx
        CVTDQ2PD xmm2, xmm2                            ;0.0 _ -4.0
        PSLLDQ xmm2, 8                                 ;4.0 _ 0.0
        paddq xmm1,xmm2                                ;4.0 _ -4.0
    
    
    
    
        ;startpos positiv
        movd xmm2,ebx
        CVTDQ2PD xmm2, xmm2
        PSLLDQ xmm2, 8                                 ;1.0 _ 0
        add ebx,2
        neg ebx
        movd xmm3,ebx
        CVTDQ2PD xmm3, xmm3                            ;0.0 _ -3.0
        paddq xmm2,xmm3                                ;1.0 _ -3.0
    
    
        _loop:                                         ;so lange, bis ecx=0
        ;~         _asmdbg_("$ecx=1")
        movdqa xmm3,xmm0                               ;1.0 _ 1.0
        divpd xmm3,xmm2                                ;1/1 _ 1/-3
        addpd xmm2,xmm1                                ;positive um 4 erhöhen, negative 4 subtrahieren
        addpd xmm4,xmm3                                ;links positive rechts negative, die summe ist PI/4
        sub ecx,1                                      ;n=n-1
    
    
        ;~      _asmdbg_()
        jnz _loop                                      ;wenn ecx<>0 dann _loop
    
    
        pshufd xmm5, xmm4, 0x4E
        addpd xmm4,xmm5                                ;PI/4 _ -PI/4
        mulpd xmm4,xmm6                                ;PI _ -PI
        movhpd qword[esi+12],xmm4                      ;PI in struct speichern
    
    
        ;~     fld qword[esi+12]
        ret
    
    
    #ce
    
    
    ;#############################################
    $n = 10000000                                      ;Anzahl Durchläufe, wird an die Anzahl der Threads angepasst! Bei 3 Threads also nur 9999999
    $pi = 0.0
    $Threads_all = 24
    ;#############################################
    
    
    
    
    ;oder für das dllcalladdress
    ;~ $binarycode = _AssembleIt2("retbinary", "Pi_Leibnitz") ;gibt nur den assemblierten code zurück
    ;~ ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $binarycode = ' & $binarycode & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    ;~ ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $binarycode = ' & $binarycode & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    ;nur für dllcalladdress() benötigt, den binarycode braucht man nur ein mal erstellen
    
    
    
    
    $binarycode = "0x8B44240489C68B0E8B5E048B5608D1E9660F57E4B804000000660F6EF0660F70F6E0F30FE6F6B801000000660F6EC0660F70C0E0F30FE6C0F7DA89D0660F6EC8F30FE6C9F7DA660F6ED2F30FE6D2660F73FA08660FD4CA660F6ED3F30FE6D2660F73FA0883C302F7DB660F6EDBF30FE6DB660FD4D3660F6FD8660F5EDA660F58D1660F58E383E90175EB660F70EC4E660F58E5660F59E6660F17660CC3"
    $tCodeBuffer = DllStructCreate("byte[" & StringLen($binarycode) / 2 - 1 & "]") ;reserve Memory for opcodes
    DllStructSetData($tCodeBuffer, 1, $binarycode)
    $ptr_asm = DllStructGetPtr($tCodeBuffer)
    
    
    
    
    
    
    For $number_Threads = 1 To $Threads_all
        PI_Leibniz($number_Threads)
    Next
    
    
    
    
    
    
    
    
    
    
    Func PI_Leibniz($number_Threads)
        $pi = 0
        $cycles = Int($n / $number_Threads / 4) * 4    ;Anpassen....easy way^^
    ;~ ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $cycles = ' & $cycles & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    
    
        Dim $Thread[$number_Threads]
        Dim $Threadexit[$number_Threads]
        Dim $Thread_struct_number[$number_Threads]
        Dim $para_struct[$number_Threads]
        Dim $param[$number_Threads]
    
    
        For $i = 0 To $number_Threads - 1
            $para_struct[$i] = DllStructCreate("uint n;uint Startpos;uint Step;align 4;double SumThread") ;n=anzahl durchläufe ; Startpos =startziffer ; Step= Schrittweite;sumThread =PI/4-Summe des Threads
            DllStructSetData($para_struct[$i], "n", $cycles) ;eax
            DllStructSetData($para_struct[$i], "Startpos", 1 + $i * 4) ;eax+4
            DllStructSetData($para_struct[$i], "Step", $number_Threads * 4) ;eax+8
            $param[$i] = DllStructGetPtr($para_struct[$i])
        Next
    
    
    ;~ $ret = _AssembleIt2("double", "Pi_Leibnitz", "ptr", $param[0])
    ;~ ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $ret = ' & $ret & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    
    
    ;~ $pi = 0
    ;~ ;Ergebnisse auslesen
    ;~ For $i = 0 To $number_Threads - 1
    ;~     $pi = $pi + DllStructGetData($para_struct[$i], "SumThread") ;alle Ergebnisse sammeln
    ;~ Next
    ;~ exit
    ;~ MsgBox(262144, 'Debug line ~' & @ScriptLineNumber, 'Selection:' & @CRLF & '$pi' & @CRLF & @CRLF & 'Return:' & @CRLF & $pi) ;### Debug MSGBOX
    
    
    
    
        $flag = 0
        $sum_Threads = 0
        $loops = 0
    
    
        $sum_Threadnumber = 0
        $sum_Threadnumber += 0                         ;summe aller Threadnummern
        For $i = 1 To $number_Threads
            $sum_Threadnumber += $i
        Next
    
    
        $t = TimerInit()
    
    
        For $i = 0 To $number_Threads - 1              ;anzahl threads starten
            $ret = DllCall("kernel32.dll", "hwnd", "CreateThread", "ptr", 0, "dword", 0, "long", $ptr_asm, "ptr", $param[$i], "long", 0, "int*", 0)
            $Thread[$i] = $ret[0]
    ;~     ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $Thread[$i] = ' & $Thread[$i] & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
        Next
    
    
    
    
        Do                                             ;threads are running
            For $i = 0 To $number_Threads - 1
                $Return = DllCall("Kernel32.dll", "uint64", "GetExitCodeThread", "ptr", $Thread[$i], "dword*", 0) ;Rückgabe (EAX) aus den Threads
                If ($Return[2] <> 259) And $Threadexit[$i] = "" Then ;ist Thread bereits fertig?
                    $Threadexit[$i] = $Return[2]
                    $sum_Threads += $i + 1             ;summe aller Threads
                    If $sum_Threadnumber = $sum_Threads Then ;alle Threads sind fertig
                        $flag = 1
                        ExitLoop                       ;alle Threads fertig
                    EndIf
                EndIf
            Next
        Until $flag = 1                                ;so lange, wie noch keine Rückgabe aus den Threads erfolgt
    
    
        For $i = 0 To $number_Threads - 1              ;alle threads terminieren
            $ret = DllCall("Kernel32.dll", "int", "TerminateProcess", "dword", $Thread[$i], "uint", 999) ;Threads löschen
            $pi = $pi + DllStructGetData($para_struct[$i], "SumThread") ;alle Ergebnisse sammeln
        Next
    
    
        $m = TimerDiff($t)
        ConsoleWrite(StringFormat("Threads: %3s   Time: %4.1fms   PI: %.12f ", $number_Threads, $m, $pi) & @CRLF)
    EndFunc                                            ;==>PI_Leibniz
    Alles anzeigen
  • Assemblercode - Noch optimierbar?

    • Andy
    • 6. Dezember 2016 um 18:46
    Zitat von alpines

    Wodurch kommt das unterschiedliche Ergebnis zustande? Die 9. Nachkommastellen stimmen nicht überein (sowie der Rest danach).

    Das hatte ich in meinem Post zum SSE/SIMD-Code schon dargestellt!
    Die FPU rechnet intern mit 80 Bit Genauigkeit, die SSE-Register sind 128 Bit breit und somit je nur 64 Bit (Double)!
    Bei 10 Millionen Durchgängen summiert sich der "Rundungsfehler".
    Abhilfe schafft, die FPU zum Rechnen mit 64Bit zu zwingen, aber wer macht das schon, die FPU ist sowieso schon schneckenlahm, da kann das Ergebnis wenigstens "genau"(er) sein....

    Ich werden mal den ASM-SSE-Code per Autoit in Threads aufsplitten lassen, schaumamal... 8o

  • Grafik/Sound Demo (InfoBox)

    • Andy
    • 5. Dezember 2016 um 20:54

    Hi!
    Sehr, sehr schön gemacht!
    Das ist ne glatte 1 mit Sternchen! :thumbup:

    Und an dem Code mitsamt der Dokumentation können sich die meisten "gestandenen Programmierer" eine dicke Scheibe abschneiden!

    May the force be with you....YODA! 8o:klatschen:

  • Assemblercode - Noch optimierbar?

    • Andy
    • 3. Dezember 2016 um 09:15
    Zitat von Xorianator

    Oder einen besseren Prozessor, das ist heute üblich.

    Und, wie oben anhand der Beispielcodes gezeigt, meistens überflüssig und falsch!
    Wohin ging denn die Entwicklung zu "besseren" Prozessoren in den letzten Jahren? Stromsparen, ok! Schneller deswegen? Kein Stück! Mal abgesehen von technischen Machbarkeitsstudien (bspw. Intel 6950X (10 Kerne, 20 Threads) für atm 1700€), die aufgrund von Strukturverkleinerungen in der Fertigung nun einige Megaherz höher getaktet werden können.
    Mehr Prozessor-Cache wo es nur geht...macht Sinn, denn die Compiler werfen Unmengen an Code/Daten in den Ring.
    Und um mal zu vergleichen: der 1700€ teuere 6950X schlägt den 200€ teuren i5-6500 bei Single-Thread-Anwendungen nicht! Oha! Wieso auch Single Thread? Werden denn nicht sämtliche Anwendungen schon so compiliert, dass sie die vielen Prozessorcores und die darin enthaltenen SIMD-Funktionen "optimal" ausnutzen? Eben nicht....
    Und genau deshalb macht es auch keinen Sinn, einen "besseren" Prozessor zu kaufen um eine Software zu beschleunigen, wenn diese Software nicht in der Lage ist die Features des Prozessors auch nur ansatzweise auszunutzen!
    Spielehersteller haben erst in den letzten Jahren begonnen, ihre Software auf Multicore/thread umzustellen. Man konnte auch den Kunden schlecht erklären, wieso für das Daddeln eines 50€-Spiels eine 1500€ teure und hunderte von Watt elektrischer Leistung verballernde Maschine gekauft werden muss!
    Die dann aber, was für ein hochgradig geistiger Dünnschiss, beim (Script-)Programmieren per Sleep() permanent im Tiefschlaf gehalten werden muss. "...Quiiiiieeek, meine Prozessorlast liegt bei 8%, quiiieeekkk, ogottogott, mein Prozessor arbeitet für das viele Geld was er gekostet hat, DAS kann und darf ja nicht sein!!!..."
    Da wird der Prozessor bis an die Grenzen übertaktet, um dann in den untersten P-states vor sich hinzuschlafen......

    Was mich an dieser Stelle bzgl. Prozessor/Hardwareverbesserung wirklich gefreut hat, war bspw. die Beschleunigung des DIV/IDIV-Befehls. Der war schon immer "teuer" und hat, nachdem u.a. dieser eine Befehl innerhalb des Prozessors beschleunigt wurde, für teilweise immense Beschleunigungen der (nicht veränderten) Software gesorgt! Wenn man sich klar macht, dass dieser Schritt ca. 30 Jahre dauerte, kann man ermessen, welche Fortschritte Software gemacht haben könnte, wenn in dieser Zeit die in den Prozessoren NICHT GENUTZTEN FEATURES benutzt worden wären... ||

    Warum bei einem "aktuellen" und unverschämt billigen Atom-Prozessor diese schnell abgearbeiteten Befehle nicht implementiert sind, sollte klar sein. NIEMAND aber auch niemand würde einen zehnfachen Preis für gerade mal 30 bis 40% mehr Leistung ausgeben! Intel käme sicherlich mit der Produktion von Atom-Prozessoren nicht mehr hinterher, davon würde jeder PC-Hersteller 8-10 in eine Kiste packen und so einen "Superserver" für wenig Geld bereitstellen können...


    Zitat von Mars

    Und wir sind hier nur langweilige Skriptsprachenkiddies

    Ein wichtiger Grundsatz in der Optimierung lautet: "Zuerst die großen Brocken!"
    Man muss herausfinden, wo eine Optimierung am meisten lohnt. Und das ist unabhängig davon, ob bei Hardware, Software oder in jedem anderen beliebigen Arbeitsablauf optimiert werden soll. Irgendwann ist ein Punkt erreicht, wo man die nur immer kleiner werdende "Verbesserung" den hohen Kosten/Aufwand gegenüberstellen muss,
    Dann macht es meistens Sinn, die Optimierung an ein weiteres, bis dato zu diesem Prozess unvoreingenommenes, Team abzugeben. Oft werden dann durch andere Lösungsansätze noch einmal Verbesserungen erreicht.


    Zitat von Xorianator

    Ein Gedanke zum loop unrolling noch @Andy - Angenommen du weißt wie viel stages deine Pipeline hat, für die Division, dann könntest du den Loop meines Theorieverständnisses nach auf diese Abrollen und als Step Größe die Anzahl der Stages nehmen.
    Andererseits Frage ich mich ob das wirklich einen Unterschied macht, da die Heuristik der Pipeline in dem Falle nur 1, maximal 2 Mal falsch liegt, und das ist wenn auf einmal nicht gesprungen sondern die Schleife verlassen wird.

    Ja, die Frage, ob es einen Unterschied macht, kann man ja ausprobieren :D
    Das habe ich auch gemacht, für SSE/SIMD. Da der Loop aber nur aus 4 Befehlen besteht, und auch Abhängigkeiten (Dependencies) innerhalb des Codes bestehen, lohnt sich das unrolling hier nicht.
    Die 10-20 Takte für den DIVPD sind zu "fett", um mit anderen Befehlen parallelisiert zu werden. Das macht in langen Sequenzen sicherlich mehr Sinn.
    Bei der Sprungvorhersage (branch-prediction) sieht es ähnlich aus. Da die handvoll Befehle sowieso alle in die Befehls-Ausführungspipeline passen, ist es auch völlig egal, ob die Sprungvorhersage IMMER FALSCH liegt! Die 4 Befehle für die "falsche" Vorhersage laufen ja parallel mit....der Inhalt der Pipelines muss nie umsortiert werden.

    Was sicherlich eine Option wäre, ist Multithreading. Man müsste mal probieren, inwieweit sich dieser Schritt bei der vergleichsweise "billigen" Berechnung lohnt.
    Durch Overhead und Threadgedöns vermute ich mal Faktor +0,7 für jeden zusätzlichen Thread. Bei einem Quadcore also ca. Faktor 3.
    Da mit AutoIt ja Multithreading in Kombination mit ( idR IMMER threadsicherem) Assemblercode ziemlich easy ist, sollte man das mal ins Auge fassen.
    Dann wäre imho für eine CPU das Limit erreicht.

    Spoiler anzeigen
    AutoIt
    #Region                                                                      ;**** Directives created by AutoIt3Wrapper_GUI ****
    #AutoIt3Wrapper_UseUpx=n
    #EndRegion                                                                   ;**** Directives created by AutoIt3Wrapper_GUI ****
    ;~ #include "AssembleIt2.au3"
    #include <Array.au3>
    
    
    ;struct mit Buchstaben erstellen, um die unterschiedliche Laufzeit der beiden Threads darzustellen
    $struct = DllStructCreate("char[4]")                                         ;platz für 4 Buchstaben
    $ptr = DllStructGetPtr($struct)
    
    
    ;platz für Bytes, der gleiche code wird von jedem Thread einzeln aufgerufen
    ;~ $ret = _AssembleIt2("retbinary", "testthreads")                              ;assemblieren
    ;~ ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $ret = ' & $ret & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    $ret = "0x8B74240489F1C1E1028B7C24080F3189D30F3129DA39CA7CF889F083C0408886CFE4AD02C3"
    ;~ ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $ret = ' & $ret & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    $thread1_struct = DllStructCreate("byte[" & StringLen($ret) / 2 - 1 & "]")   ;asmcode
    $ptr_asm = DllStructGetPtr($thread1_struct)
    ;bytecode in struct schreiben
    DllStructSetData($thread1_struct, 1, $ret)
    
    
    
    
    #cs testthreads
        use32
        mov esi,[esp+4]                                                          ;parameter laufzeit
        mov ecx,esi                                                              ;
        shl ecx,2                                                                ;vervierfachen, thread 1 soll doppelt so lange laufen wie thread 2
        mov edi,[esp+8]                                                          ;Integer belegen
        ;Zeitschleife
        rdtsc                                                                    ;counter in eax
        mov ebx, edx                                                             ;obere 32 Bit merken  ebx=timerinit()
        _wait:
        rdtsc                                                                    ;counter in eax
        sub edx,ebx                                                              ;timerdifferenz von aktuellem timestamp zum gemerkten timestamp ebx=timerdiff(ebx)
        cmp edx,ecx                                                              ;ecx einheiten (2^32 Takte) vergangen?
        jl _wait                                                                 ;wenn weniger, dann _wait
        ;zeitschleife ende
        mov eax,esi                                                              ;parameter in eax
        add eax,64                                                               ;einen ansi-Buchstaben machen
        mov byte[$ptr-1+esi],al                                                   ;buchstabe in struct schreiben
        ret
    #ce
    
    
    $hgui = GUICreate("Multithread Test", 400, 400)
    $lbl = "Es werden mehrere Threads gestartet, währendessen " & @CRLF & "läuft das AutoIt-Script weiter..."
    $lbl = GUICtrlCreateLabel($lbl, 10, 10, 400, 50)
    $btn = GUICtrlCreateButton("Los gehts!", 200, 300, 100, 30)
    
    
    
    
    $uhr = GUICtrlCreateLabel("", 10, 60, 200, 30)                               ;uhr
    
    
    $lbl_struct = GUICtrlCreateLabel("", 10, 100, 200, 30)
    $lbl_runtime = GUICtrlCreateLabel("", 10, 150, 200, 100)
    $lbl_ende = GUICtrlCreateLabel("", 10, 250, 200, 30)
    
    
    GUISetState()
    
    
    
    
    While Sleep(10)
        $msg = GUIGetMsg()
        If $msg = -3 Then Exit
        If $msg = $btn Then _threads()
        $zeit = "Zeit: " & @HOUR & ":" & @MIN & ":" & @SEC & ":" & @MSEC
        GUICtrlSetData($uhr, $zeit)
    WEnd
    
    
    
    
    
    
    Func _threads()
        ;3 Threads vom gleichen Maschinencode aufrufen, das Autoitscript läuft weiter
        ;der zweite Thread läuft doppelt so lange wie der erste
        ;jeder Thread schreibt nach einer gewissen Zeit einen Buchstaben ascii(64+param) in die struct
        ;der erste Thread schreibt ein A an die erste Position
        ;der zweite Thread schreibt ein C an die 3. Position
        ;der dritte Thread schreibt ein B an die 2. Position
    
    
        DllStructSetData($struct, 1, "XXXX")
    
    
        $param = 2                                                               ;B
        $ret3 = DllCall("kernel32.dll", "hwnd", "CreateThread", "ptr", 0, "dword", 0, "long", $ptr_asm, "ptr", $param, "long", 0, "int*", 0)
        $param = 3                                                               ;C
        $ret1 = DllCall("kernel32.dll", "hwnd", "CreateThread", "ptr", 0, "dword", 0, "long", $ptr_asm, "ptr", $param, "long", 0, "int*", 0)
        $param = 1                                                               ;A
        $ret2 = DllCall("kernel32.dll", "hwnd", "CreateThread", "ptr", 0, "dword", 0, "long", $ptr_asm, "ptr", $param, "long", 0, "int*", 0)
    
    
        $t = TimerInit()
        Local $flag1 = 0, $flag2 = 0, $flag3 = 0, $runtime = ""
        While Sleep(10)                                                          ;threads are running
            $zeit = "Zeit: " & @HOUR & ":" & @MIN & ":" & @SEC & ":" & @MSEC
            GUICtrlSetData($uhr, $zeit)
            GUICtrlSetData($lbl_struct, DllStructGetData($struct, 1))
    
    
            $eax1 = DllCall("Kernel32.dll", "int", "GetExitCodeThread", "ptr", $ret1[0], "dword*", 0) ;Rückgabe (EAX) aus den Threads
            $eax2 = DllCall("Kernel32.dll", "int", "GetExitCodeThread", "ptr", $ret2[0], "dword*", 0)
            $eax3 = DllCall("Kernel32.dll", "int", "GetExitCodeThread", "ptr", $ret3[0], "dword*", 0)
            ToolTip("AutoIt ist nicht geblockt!" & @CRLF & "EAX1 = " & $eax1[2] & "     EAX2 = " & $eax2[2] & @CRLF & "     EAX3 = " & $eax3[2] & @CRLF & "structinhalt: " & DllStructGetData($struct, 1))
    
    
            ;sind die threads alle fertig?
            $m = TimerDiff($t)
            If ($eax1[2] <> 259) And $flag1 = 0 Then
                $runtime &= "1. Thread fertig: " & Int($m) & " ms" & @CRLF
                $flag1 = 1
            EndIf
            If ($eax2[2] <> 259) And $flag2 = 0 Then
                $runtime &= "2. Thread fertig: " & Int($m) & " ms" & @CRLF
                $flag2 = 1
            EndIf
            If ($eax3[2] <> 259) And $flag3 = 0 Then
                $runtime &= "3. Thread fertig: " & Int($m) & " ms" & @CRLF
                $flag3 = 1
            EndIf
            GUICtrlSetData($lbl_runtime, $runtime)
            If ($eax1[2] <> 259) And $eax2[2] <> 259 And $eax3[2] <> 259 Then ExitLoop ;so lange, wie noch keine Rückgabe aus den Threads erfolgt
        WEnd
        DllCall("Kernel32.dll", "int", "TerminateProcess", "ptr", $ret1[0], "uint", 0) ;Threads löschen
        DllCall("Kernel32.dll", "int", "TerminateProcess", "ptr", $ret2[0], "uint", 0)
        DllCall("Kernel32.dll", "int", "TerminateProcess", "ptr", $ret3[0], "uint", 0)
        ToolTip("")
    
    
    
    
        GUICtrlSetData($lbl_ende, "Geschafft!")
        ;MsgBox(0, "Structinhalt nach dem Beenden der beiden Threads", DllStructGetData($struct, 1))
    
    
    
    
    
    
    
    
    EndFunc                                                                      ;==>_threads
    Alles anzeigen


    Da aber der Leibniz-Algorithmus sehr gut zu parallelisieren ist, wäre es interessant, mal OpenCL auszuprobieren. Leider unterstützen die meisten Grafikkarten keine (dann nur per Softwareemulation) oder nur sehr langsame Double-Berechnungen. Die Beschleunigung durch die hunderte GPU-Prozessoren würde imho durch die Emulation von Double-Berechnungen mehr als aufgefressen.

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™