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

  • WinActivate unter Windows 10 scheitert scheinbar

    • Andy
    • 6. September 2017 um 19:21

    Hi,

    genau zu diesem Thema hatte sich nach der Umstellung auf Win10 ein Kollege bei mir gemeldet, weil dessen von mir erstellte Scripte AB UND ZU falsche Ergebnisse liefern, wegen ebendiesem nicht funktionierenden WinActivate()/WinWaitActive().

    Bei Nachforschungen hat sich ergeben, dass das Script einige Tage problemlos läuft (Logfiles) um dann völlig sporadisch das zu steuernde Fenster nicht mehr zu aktivieren.

    Die Logfiles weisen keinen einzigen Fehler seitens des AutoIt-Scripts aus, d.h. AutoIt bekommt die Info, das Fenster der zu steuernden Anwendung ist im Vordergrund, was allerdings nicht stimmt.

    Das Problem liegt in der zu steuernden Anwendung (keine API vorhanden...), in dem ein einziges von ca. 15 auszufüllenden EDIT-Feldern nicht mit ControlSend() beizukommen ist, so dass ich (nur für dieses Feld) auf Send() angewiesen bin.

    Wenn natürlich das Fenster nicht aktiv ist, führt Send() ins leere, der Feldinhalt wird nicht geändert und infolge dessen bei der weiteren Scriptausführung werden falsche Ergebnisse produziert.

    Die werden dann zwar abgefangen, und idR. durch einen Neustart des Scripts (welches dann meist fehlerfrei durchläuft) bereinigt, aber das kann ja nicht die Lösung sein.

    Das Script läuft seit Jahren problemlos, vor einigen Wochen wurde der Rechner auf Win10 geupdatet, seitdem gibt es diese sporadischen Aussetzer.

    Auf dem Rechner läuft neben der obligatorischen Serververbindung ausschliesslich eine Excel-Instanz welche mit dem AutoIt-Script kommuniziert, welches wiederum die Anwendung steuert.

    Ich würde liebend gerne, da ich sowieso so gut wie alles andere per VBA programmiere, in diesem Fall auf AutoIt verzichten, aber erstens möchte ich die Ursache wissen, und zweitens ist mir die Zeit zu schade, mehrere hundert AutoIt-Zeilen in mehrere tausend VBA-Zeilen zu überführen.

    Ich habe mehrfach im Script die Kombination WinActivate()/WinWaitActive() verwendet, um Fehler zu provozieren, es werden Menüs und mehrere Unterfenster völlig problemlos erkannt, auch wenn die zu steuernden Fenster und Controls alle "unsichtbar" sind....

  • Poker-Card-Machine v3

    • Andy
    • 24. August 2017 um 23:04

    Hallo Oscar!

    Klasse Arbeit, so wie immer :o) !

    Eins habe ich beim Spielen aber festgestellt, wenn man vor dem "Start" auf die Karten klickt, dann werden diese nach "Start" nicht umgedreht. Ist das Absicht?
    Ansonsten ist mir die Auswahl der Möglichkeiten egal! :whistling:

  • String auf spezielles Format untersuchen

    • Andy
    • 17. August 2017 um 00:35
    Zitat von Yjuq

    By the way - Ich habe den Namen Make-Grafik abgelegt. Ist dir das aufgefallen oder hast du mich lediglich am Profilbild erkannt? xD

    Abgelegt hin- oder her.....juckt mich ehrlich gesagt nicht, denn Namen werden keine abgelegt. X/
    DU bist für MICH eben Make-Grafik, damit verbinden sich alle schönen gemeinsam hier im Forum verbrachten Stunden und so soll es (jedenfalls für mich) auch weiter so sein. Und da gehört der "richtige" Name auch zur Person ;)

    Zitat von Yjuq

    €dit: Vergebt mir, ich bin in RegEx wirklich nicht mehr fitt. Ich war es mal aber ich hab das nun seit 3 Jahren nicht mehr gebraucht. Hab mich gerade mal so in AspirinJunkie sein Pattern eingelesen und verstanden.

    Ich bin auch nicht fit in Regex, wie du siehst führen viele Wege zum Ziel!
    Genau wie beim Programmieren gehe ich davon aus, dass mit 5-10% der "Befehle" 90% aller Lösungen zu erstellen sind. Prinzip verstanden, umgesetzt, fertig. Der Rest ist learning by doing, Und wenn man ein Regex nur alle 3 Monate braucht, muss man sicherlich kein "Crack" sein, um eine Lösung zurechtzustricken.
    Und mit so einer "Steilvorlage" wie deiner Beschreibung im Startpost schonmal garnicht 8)

  • String auf spezielles Format untersuchen

    • Andy
    • 16. August 2017 um 23:22

    Hallo MakeGrafik! ^^

    Wenn du solch schöne Regeln aufstellst, dann bietet sich Regex wirklich an...
    Das kann man dann 1:1 übersetzen!
    Bspw. so:

    Code
    #include <array.au3>
    
    
    $text = "1" & @CRLF & _
            "2.3" & @CRLF & _
            "-0" & @CRLF & _
            "-0.12e-1" & @CRLF & _
            "22.123912e+3" & @CRLF & _
            "0e123" & @CRLF & _
            "00.7" & @CRLF & _
            "0.007" & @CRLF & _
            "bla" & @CRLF & _
            "be34rtz" & @CRLF & _
            "1..9.456e3" & @CRLF & _
            "e4" & @CRLF & _
            "-12.63" & @CRLF & _
            "--455" & @CRLF & _
            "3.4ee44"
    
    
    
    
    
    
    $ret = StringRegExp($text, "(?m)^[-+]?\d{1}[123456789]*(?:\.{1}\d+)*(?:(?:e\+|e\-|e){1}\d+)?$", 3)
    _ArrayDisplay($ret)
    
    
    
    
    $textarray = StringSplit($text, @CRLF, 3)
    $ergebnis = ""
    For $teil In $textarray
        $ergebnis &= $teil & "     Regex: " & (StringRegExp($teil, "(?m)^[-+]?\d{1}[123456789]*(?:\.{1}\d+)*(?:(?:e\+|e\-|e){1}\d+)?$", 0) ? "True!" : "False!") & "     _isnumber: " & _IsNumber($teil) & @CRLF
    Next
    MsgBox(0, 0, $ergebnis)
    
    
    
    
    
    
    Func _IsNumber($sParam)
        Local $aParam = StringToASCIIArray($sParam)
        Local $iCase
        For $i = 0 To UBound($aParam) - 1
            Switch $iCase
                Case 0                       ; Minus-Zeichen?
                    If $aParam[$i] <> AscW("-") Then $i -= 1
                    If $i = UBound($aParam) - 1 Then Return False
                    $iCase = 1
                Case 1                       ; 1 bis 9 oder 0?
                    If $aParam[$i] >= AscW("1") And $aParam[$i] <= AscW("9") Then
                        $iCase = 2
                    ElseIf $aParam[$i] == AscW("0") Then
                        $iCase = 3
                    Else
                        Return False
                    EndIf
                Case 2                       ; Ziffer?
                    If $aParam[$i] < AscW("0") And $aParam[$i] > AscW("9") Then
                        $i -= 1
                        $iCase = 3
                    EndIf
                Case 3                       ; Punkt-Zeichen oder Potenz?
                    If $aParam[$i] = AscW(".") Then
                        $iCase = 4
                        If $i = UBound($aParam) - 1 Then Return False
                    ElseIf $aParam[$i] = AscW("e") Or $aParam[$i] = AscW("E") Then
                        $iCase = 5
                        If $i = UBound($aParam) - 1 Then Return False
                    Else
                        Return False
                    EndIf
                Case 4                       ; Ziffer oder Potenz?
                    If $aParam[$i] < AscW("0") And $aParam[$i] > AscW("9") Then
                        If $aParam[$i] <> AscW("e") Or $aParam <> AscW("E") Then Return False
                        If $i = UBound($aParam) - 1 Then Return False
                        $iCase = 5
                    EndIf
                Case 5                       ; Plus oder Minus?
                    If $aParam[$i] <> AscW("+") Or $aParam[$i] <> AscW("-") Then $i -= 1
                    $iCase = 6
                Case 6                       ; Ziffer?
                    If $aParam[$i] < AscW("0") And $aParam[$i] > AscW("9") Then Return False
            EndSwitch
        Next
        Return True
    EndFunc                                  ;==>_IsNumber
    Alles anzeigen

    Ich habe mal deine Funktion testweise mitlaufen lassen, die ist noch verbesserungswürdig^^

    //EDIT so ist das, wenn man erst nach 2h auf "Post abschicken" klickt...AspirinJunkie hat das "schönere" Regex :thumbup:

  • Große Dateien einlesen? Alternative zu FileReadLine & FileReadToArray?

    • Andy
    • 21. Januar 2017 um 12:12

    @Oscar,
    meine Version, die Datei per Win-API einzulesen, hat ja nicht nur den Grund schneller zu sein, sondern verschiedene Blockgrößen für das Lesen einstellen zu können.
    Damit ist es möglich, wesentlich größere Dateien (bei Win64 NTFS bspw. 16 Exbibyte (EiB) = 2^60 Byte = 1 152 921 504 606 846 976 Byte) einzulesen!

    Per SetFilePointer() kannst du irgendeine Stelle in der Datei "anspringen", und von dort aus eine (vom allozierbaren Speicher abhängige) Größe von Bytes einlesen.

    Das Problem stellt sich doch genau wie in diesem Post beschrieben dar....
    User will eine Datei "zeilenweise" in ein Array einlesen. So weit, so gut. Mir stellt sich da die Frage der Sinnhaftigkeit dieses Vorhabens, da eine Textdatei bereits ein Array IST! Aber das ist nicht das Problem.
    Das Problem, insbesondere bei AutoIt, ist die extrem langsame interne Kopiererei und Anforderung von Speicher intern. Für jede Kopieraktion innerhalb des Speichers wird ca. doppelt so viel Speicher wie nötig angefordert. Wenn man den Dateimanager offen hat und per AutoIt eine ca. 1 Gig große Datei per FileRead() einzulesen versucht, kann man sehen, dass AutoIt irgendwann bei ca. 2.8 Gig "Speicherverbrauch" abstürzt.

    Fülle per API-Fileread einen Speicherpuffer (DllStructcreate() ) mit einem Dateiinhalt von 520MB, das dauert selbst auf meinem langsamen Rechner nur ca. 1 Sekunde. Kommt gut hin, meine SSD schafft angeblich 500MB/s aber du weißt ja, der Ingenieur teilt durch 2 und ist auf der sicheren Seite. :D
    Genau so schnell lassen sich die Blöcke von 500MB Größe einer mehreren Gigabytes großen Datei einlesen. DAS geht sehr schnell, "nur" die Weiterverarbeitung ist langsam....insbesondere, wenn man auch noch "langsam" programmiert bzw. "langsame" Funktionen verwendet.

    Ein Bekannter sucht aktuell in hunderten von ca. 4Gig großen Videodateien nach irgendwelchen "Markern". Ich habe von Video nicht viel Ahnung, interessiert mich aber auch nicht, hauptsache die Marker werden in den 4 Gig innerhalb von ca. 10-15 Sekunden gefunden/ersetzt.
    Auf meinem Rechner die Datei(en) in Blöcken von 500MB Größe einlesen dauert ca. 1 Sekunde, die Suche nach den "Markern" innerhalb dieses Blocks dauert ca. 1 Sekunde, voila...
    Ich hätte gerne mit dem unschlagbar schnellen Autoit-StringRegExp() gesucht, leider dauert das oben beschriebene, AutoIt-interne kopieren des Strings aus der DllStruct 5x länger als die eigentliche Suche... ;( So musste ich (leider) auf ASM-SIMD ausweichen (aus Übungszwecken nach einer C-Dll portiert), in Verbindung mit Multithreading für die Suche wird nun eine 4Gig große Datei mit 450MB/s gelesen und durchsucht/ersetzt! Dieses schnelle Lesen ist nur infolge RAID 5 und schnellen Platten möglich, das eigentliche Suchen/Ersetzen wird in der Zeit durchgeführt, in der der nächste Datenblock geladen wird.
    "Von Hand" also Videodatei in Editor laden, per Script die Marker setzen und abspeichern dauert lt. seiner Aussage "ewig", also mehrere Minuten.

  • Einlesen von riesigen Excel Tabellen

    • Andy
    • 20. Januar 2017 um 13:33
    Zitat von alpines

    Du hast doch sicherlich genug Speicherplatz um die Datenbank zu backuppen bevor du ihr ne Liste an Queries an den Kopf schmeißt?

    Und dann? Dem Kunden sagen "..wenn es nicht klappt, dann spiel das Backup ein!" ? Das ist die ultimative Darstellung von Inkompetenz! DAS wird sich kein Geschäftspartner bieten lassen, soviel steht fest.
    Ich persönlich hätte kein Problem, den Zwischenschritt über eine CSV- oder wasauchimmer-Datei zu gehen. Diese ist recht simpel mit diversen Programmen, ggf. auch AutoIt, prüf- und editierbar.

    Einige hundert kilobytes an Daten sind völlig problemlos handlebar, bei einigen hundert MB wird´s da schon kritischer. Wenn ich aber die Angabe "einige tausend Artikel" lese, und den Zeitrahmen eines Azubis von 2-3 Stunden Bearbeitung wöchentlich sehe, dann sehe ich die Datenmenge als "pillepalle".

  • Button betätigen nach Ereignissänderung

    • Andy
    • 18. Januar 2017 um 13:20
    Zitat von Oscar

    Da bleibt wohl nur PixelGetColor.

    oder "PushTheButton" PushTheButton, ermöglicht Mausklick auf sonst nicht erreichbare Grafiken UPDATE 1.36
    Ich hatte neulich erst genau für eine Maschinensteuerung das Script im Einsatz.

    //EDIT die Prospeed.dll benötigt man übrigens nicht, bei sehr großen "Suchbildern" ist sie allerdings etwas schneller als AutoIt.
    //EDIT2 ich habe gerade gesehen, dass die Fensterdarstellung für Win7/Win10 besser sein könnte....das Script ist schliesslich aus 2009^^

  • Ausgänge ansteuern mit AutoIt

    • Andy
    • 17. Januar 2017 um 20:23

    Hi,
    zu allererst diese Links, die behandeln das Thema Arduino Und ESP8266.
    AutoIt und Arduino

    Problem mit nem Vorhaben und meinem Arduino
    Arduino als Fernbedienungsersatz

    Zitat von presenter-test

    Es geht darum Digitale Ausgänge zu schalten.

    QUARK! Kein Mensch auf der Welt will "digitale Ausgänge schalten". WAS WILLST DU GENAU MACHEN?

  • Große Dateien einlesen? Alternative zu FileReadLine & FileReadToArray?

    • Andy
    • 17. Januar 2017 um 19:07

    Die WIN-API-Funktionen sind bei mir Faktor 4 schneller als die AutoIt-Pendants.
    Oscars 260MB-Datei wird mit meinem Script in knapp 3 Sekunden eingelesen, mit Oscars AutoItscript dauert es wie gesagt eine Minute! Ich weiß nicht, was da so dermaßen schief läuft...

    Code
    >Running:(3.3.14.2):C:\Program Files (x86)\AutoIt3\autoit3.exe "D:\Autoitscripte\test33.au3"    
    --> Press Ctrl+Alt+Break to Restart or Ctrl+Break to Stop
    69516.9044993424

    ;(;(
    //EDIT, na gut, wenn ich die Tooltip-Zeile auskommentiere, wird die Einlese-Zeit auf 18 Sekunden reduziert. Immer noch 6x langsamer als per Win-API

  • Große Dateien einlesen? Alternative zu FileReadLine & FileReadToArray?

    • Andy
    • 17. Januar 2017 um 00:14

    Hi,

    das Lesen großer Dateien massiv zu beschleunigen hatten wir HIER schon einmal...AspirinJunkie hat da eine wirklich klasse Funktion erstellt! (siehe Anhang Script)
    Diese Funktion hat genau wie alle Fileread-Funktionen bei sehr großen Dateien den Nachteil, dass AutoIt mit einem Speicherfehler abstürzt....

    Sehr große Dateien liest man blockweise per SetFilePointer aus. Zu beachten ist, dass die Datei schon per WIN_API-Funktion zu öffnen und weiterzubearbeiten ist.
    Datei öffnen, SetFilePointer, Datenblöcke auslesen, so stellt sich das dar.
    Die 520MB große Beispieldatei (auskommentierte Zeilen ausführen und Kaffee trinken gehen) wird erstellt, jede Zeile besteht aus 50 Stellen, wobei die Zeilennummer rechts ausgerichtet ist (einfach mal in Scite öffnen)
    Das eigentliche Lesen der Datei in Blöcken dauert bei mir nur ca.5 Sekunden (Laptop). In der Console werden jeweils die ersten und letzten beiden Zeilen eines jeden Blocks angezeigt.

    AutoIt
    #include <WinAPI.au3>
    
    
    Global $kerneldll = DllOpen("kernel32.dll")
    
    
    Global $sFilename = @ScriptDir & '\!bigdata.txt'
    ;~ Global $sData = ''
    ;~ For $j = 1 To 10000000
    ;~     $sData &= StringFormat("%050s", $j) & @CRLF
    ;~     If Mod($j, 50000) = 0 Then ToolTip($j)
    ;~ Next
    ;~ $hfile = FileOpen($sFilename, 2)
    ;~ FileWrite($hfile, $sData)
    ;~ FileClose($hfile)
    
    
    
    
    $t = TimerInit()
    $filesize = FileGetSize($sFilename)
    $Zeilen = $filesize / 52
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $Zeilen = ' & $Zeilen & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    
    
    $hfile = _WinAPI_CreateFile($sFilename, 2, 2)
    $blocksize = 5200000                                                             ;gleich große Blöcke                                          ;50MB
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $blocksize = ' & $blocksize & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    
    
    $nbytes = 0
    Local $blockstruct = DllStructCreate("char[" & $blocksize & "]")
    
    
    
    
    For $i = 0 To $filesize Step $blocksize
        FileSetPos($hfile, $i, $FILE_BEGIN)
        DllCall($kerneldll, "bool", "SetFilePointer", "handle", $hfile, "long", $i, "long", 0, "dword", $FILE_BEGIN)
        _WinAPI_ReadFileXXX($hfile, DllStructGetPtr($blockstruct), $blocksize, $nbytes)
    ;~     ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $nbytes = ' & $nbytes & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
        $a = DllStructGetData($blockstruct, 1)
        $left = StringLeft($a, 104)
        ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $left = ' & $left & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
        $right = StringRight($a, 104)
        ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $right = ' & $right & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    Next                                                                             ;ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $a = ' & $a & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    
    
    ConsoleWrite(StringFormat("%i MB Datei geladen in %f ms", Int($filesize / 1000000), Int(1000 * TimerDiff($t)) / 1000) & @CRLF & @CRLF)
    Alles anzeigen

    Hier nochmal AspirinJunkie´s Funktion für "kleine" Dateien (bis ca. 300MB)
    CSV Datei Zeilen zählen - extrem schnell - GNUWin32


    @Oscar, wenn ich deine Scripte aus Post #16 ausführe, dann dauert das bei mir (Laptop mit SSD) länger als eine Minute...könnte es sein, dass bei dir irgendwelche Caching-Geschichten mitspielen? Ich hatte schon damals (s. Thread bzgl. AspirinJunkie´s Funktion) festgestellt, dass es große Unterschiede beim Dateilesen gibt, wenn Windows bestimmte Dateien cached! //EDIT hast das ja auch gepostet, ich war zu langsam... :thumbup:

  • Window ID auslesen und überprüfen wenn beendet

    • Andy
    • 13. Januar 2017 um 09:04

    Welche Ergebnisse über das "Speichern unter"-Fenster werden über das "AutoIt Window Info"-Tool ermittelt?

    Zitat von marccore

    Ich kriege immer nur die Info über das Hauptfenster.

    Um welches Programm (ggf Screenshot der Fenster) geht es überhaupt? Welches Programmierframework wurde für dieses Programm verwendet?

  • Gitternetz (edit: gelöst)

    • Andy
    • 2. Januar 2017 um 17:54

    Ohne Gedöns! :D

    Code
    #include <GDIPlus.au3>
    
    
    _GDIPlus_Startup()
    
    
    ;$datei = "fullscreen.bmp"
    
    
    $datei = FileOpenDialog("Bilder", @ScriptDir, "Bilder (*.jpg;*.bmp;*.png)")
    
    
    $bitmap = _GDIPlus_BitmapCreateFromFile($datei)
    
    
    $hbmp = _GDIPlus_BitmapCreateHBITMAPFromBitmap($bitmap)
    
    
    $hImage = _GDIPlus_BitmapCreateFromHBITMAP($hbmp)
    
    
    $iX = _GDIPlus_ImageGetWidth($hImage)
    $iY = _GDIPlus_ImageGetHeight($hImage)
    
    
    $xstep = $iX / 22
    $ystep = $iY / 14
    
    
    $hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage)
    
    
    $hPen = _GDIPlus_PenCreate()
    
    
    For $x = 0 To $iX Step $xstep
        _GDIPlus_GraphicsDrawLine($hGraphic, $x, 0, $x, $iY, $hPen)
    Next
    For $y = 0 To $iY Step $ystep
        _GDIPlus_GraphicsDrawLine($hGraphic, 0, $y, $iX, $y, $hPen) ;x
    Next
    
    
    
    
    _GDIPlus_ImageSaveToFile($hImage, "GDIPlus_Image_test.bmp")
    ShellExecute("GDIPlus_Image_test.bmp")
    Alles anzeigen


    @Oscar, ich würde in der Zeile Global $iGridX = Int($iWidth / 22), $iGridY = Int($iHeight / 14) [i]; die Gitter-Breite und -Höhe errechnen[/i] die INT weglassen, da sonst bei "ungeraden" Breiten/Höhen hässliche Reste rechts und unten am Rand übrigbleiben.
    GDI rundet idR Floatzahlen zum passenden Integer.

  • probleme mit dem befehl ControlSend

    • Andy
    • 1. Januar 2017 um 11:07

    Hi,
    dir fehlt die ControlID, welche du mit dem Tool "AutoIt Window Info" (im AutoIt-Verzeichnis) erhälst.
    Schau dir in der Hilfe an, welche Parameter du benötigst!
    Weiterhin solltest du dein Script komplett oder zumindest die für das Verständnis nötigen Teile posten.

  • OpenCl goes AutoIt Update 31.Dezember 2016

    • Andy
    • 31. Dezember 2016 um 13:48

    Ich habe auf verschiedenen Rechnern unterschiedliche AutoItversionen, allerdings keine Fehlermeldungen bzgl. GDIConstants.au3...

    Omfg, die GTX970 geht ja ab....

  • OpenCl goes AutoIt Update 31.Dezember 2016

    • Andy
    • 31. Dezember 2016 um 13:31

    Hi zusammen,
    aus aktuellem Anlass habe ich die OpenCL-Funktionen weiter angepasst und aufgefrischt.

    Bitte die Beispielscripte testen, ggf. auch die Ergebnisse der Devices.au3 posten. Danke!

    Es sollten die 64-Bit-Versionen der Scripte problemlos laufen, Geschwindigkeitsunterschiede zu 32Bit sind (bei mir zumindest) keine feststellbar,

    Getestet wurde auf einem Intel-Notebook mit frisch installiertem und auf die neueste Version geupdateten Win10.
    Im Prozessor ist ein Grafikchip integriert, dazu auf dem Board zusätzlich eine Nvidia-GPU. Die Tests liefen ohne Treiberupdates problemlos sowohl auf der CPU als auch auf den GPU´s.

    Ich habe ein "Auswahlmenü" zur Verfügung gestellt, um das Gerät, auf welchem der Code ausgeführt werden soll, auswählen zu können.

    Zwischenablage01.jpg
    Dazu im Vergleich, meine "alte" Kiste

    Dateien

    AMD.jpg 34,96 kB – 0 Downloads
  • Assemblercode - Noch optimierbar?

    • Andy
    • 29. Dezember 2016 um 06:48

    Oha!
    Danke erstmal für die Tests!
    Meine Ergebnisse sind mit einem FX6300@3.5GHz (Bulldozer) wie bei euch recht identisch, ca.1300ms... Im Vergleich doch recht schnell...

    @chesstiger, ja, das gefällt mir ganz und garnicht... :huh:
    Google befragen mit "avx slower than sse" zeigt, dass nicht nur ich damit ein Problem habe. Wobei man fairerweise sagen muss, dass bei vielen dieser Aussagen/Fragen gezeigt wird, wie man durch Umstellen des Codes die Performance signifikant verbessern kann. Die Compiler brauchen also massiv Hilfe seitens des Entwicklers!

    Angeblich sollen die "neueren" INTEL-Prozessoren (Skylake, Kaby Lake) etwas besser bei AVX abschneiden, also abwarten...
    Wie es aussieht, verwenden sowohl AMD als auch INTEL "nur" die 128-Bit breiten Register und "mappen" die 256- bzw. 512 Bit breiten AVX-Register. Heisst also, dass bei AVX bspw. beim Addieren nicht 4 Doubles gleichzeitig addiert werden, sondern "nacheinander" 2x2 per SSE... :S
    //EDIT Dazu kommt noch, dass das DIV genau wie ein SQRT bei AVX "intern" sowieso nur als SSE ausgeführt wird, daher also kein Wunder, dass die Laufzeiten identisch sind!

    Was man aber auch nicht verschweigen sollte ist, dass die Berechnung von PI im vorliegenden Programm nur von 2 Befehlen ausgeführt wird, Division und Addition in einer extrem kurzen Schleife. Die Prozessoren haben keinerlei Möglichkeit, ihre Pipelines optimal zu füllen, der aufwendige und dadurch langsame DIV bricht denen in jedem Schleifendurchlauf das Genick.

    In "realer" Software mit Speicher/Cache-zugriffen gibt es je nach Speicheranbindung sicherlich Unterschiede zugunsten AVX. Auch die Befehle wie bspw. FMA bringen dann sicher etwas Performance.

  • SynSug - Syntaktischer Zucker für AutoIt (Update v1.1.0 Dictionaries)

    • Andy
    • 28. Dezember 2016 um 23:21

    Jetzt hab ich mich endlich aufgerafft, auch mal bissl C zu schreiben, da kommst du mit dem Gedöns in AutoIt! :Face:

    Aber sonst...ein klares :thumbup:

  • Assemblercode - Noch optimierbar?

    • Andy
    • 28. Dezember 2016 um 23:14

    Für diejenigen, welche einen Prozessor haben welcher AVX unterstützt, hier der Code:

    C
    // Compilerflags: -mavx -std=c99 -O3
    #include <sys/time.h>
    #include <stdio.h>
    #include <immintrin.h>
    #define LOOPSEACH 10000000
    double ret[4] __attribute__((aligned(16)));
    int main (void){
    	struct timeval tim;
        gettimeofday(&tim, NULL);
        __m256d a = {1.0L,  1.0L, 1.0L,  1.0L};  //  1/x
        __m256d b = {8.0L, -8.0L, 8.0L, -8.0L}; //  positive nenner +8 , negative nenner -8
        __m256d c = {1.0L, -3.0L, 5.0L, -7.0L}; //
    	__m256d d; // Zwischenspeicher
        __m256d erg = {0.0L, 0.0L,0.0L, 0.0L}; //ergebnis = summe aus 1/c
    	 for(int i = 0; i < LOOPSEACH/4; i++) {  //die Variablen bestehen jeweils aus 4x64Bit DOUBLE
    		d = a;            //immer 1.0 1.0
    		d = d / c;        //_mm256_div_pd(d,c);     // 1/c1   1/-c2
    		c = c + b;        //_mm256_add_pd(c,b);     // c1=c1+4   c2=c2-4
    		erg = erg+d;      //_mm256_add_pd(erg,d); // erg = erg + (1/c1 + 1/-c2)
    	 }
    	_mm256_store_pd(ret,erg);
    	struct timeval tim2;
        gettimeofday(&tim2, NULL);	
    	printf("ret1= %.12f  ret2= %.12f  ret3= %.12f  ret4= %.12f  summe= %.14f \n" ,ret[0],ret[1],ret[2],ret[3],(ret[0]+ret[1]+ret[2]+ret[3])*4);
        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

    diesen Code mit den Flags -mavx -O3 hier eingetragen http://godbolt.org , sieht man, was der GCC daraus macht....sehr schick, der "inner loop" besteht aus den schon zuvor beschriebenen 5 Zeilen:

    Code
    .L2    sub     eax, 1
            vdivpd  ymm2, ymm4, ymm0
            vaddpd  ymm0, ymm0, ymm3
            vaddpd  ymm1, ymm1, ymm2
            jne     .L2

    diesmal werden 4 DOUBLE gleichzeitig berechnet, daher nur 1/4 der Schleifendurchläufe!

    Gegenüber im vorhergehenden Post#43 gezeigten Code wurden nur die "langen" (256Bit) AVX-Variablentypen und Intrinsics im C-Code angepasst!
    Das ist dermaßen einfach, da frag ich mich ernsthaft, warum diese Techniken/Verfahren nicht permanent eingesetzt werden...

    Auf einem AMD FX-6300 ist der AVX-Code leider nicht doppelt so schnell, sondern nur gleich schnell wie der SSE-Code, fu** AMD! Da wurde bei der Implementierung geschlampt! Könnte jemand mit INTEL-Prozessor mal die Laufzeit der beiden Programme testen?
    AVX-SSE.zip
    Ich habe jetzt keine Abfrage programmiert, ob der Prozessor AVX unterstützt, wenn nicht, crashed die exe. :Glaskugel:

    Wer Interesse an einer unkomplizierten C++-Umgebung hat, in welcher die oben beschriebenen Codes problemlos laufen, dem empfehle ich das MinGW-Developer-Studio hier http://vaultec.mbnet.fi/mingwstudio.php
    Dort aber UNBEDINGT den Installer mit dem GCC4 runterladen!

  • Frames per Second richtig messen (Verständnisproblem)

    • Andy
    • 15. Dezember 2016 um 07:34
    Zitat von Cape-City

    und was FPS im Grunde bedeutet,

    Was heißt "im Grunde"?
    FPS sind FPS. Also irgendwie im Script erzeugte Bilddarstellungen pro Sekunde. Und da gibts auch nichts an der "Bedeutung" auszulegen!
    Bilder zählen, Zeit festlegen, FPS als Bilder pro Zeit ermitteln. Fertig!
    Die Bilder zählen erfolgt mit einer simplen Variable, die Zeit wird über einen (EINEN!) wieauchimmerimplementierten Timer festgestellt. Sobald mehrere Timer/Zähler involviert sind, die auch noch voneinander abhängen, ist das Ergebnis nicht mehr einfach nachzuvollziehen.
    So lange du sicherstellen kannst, dass deine Zeitmessung funktioniert, stimmen zwangsläufig auch die FPS!

  • Frames per Second richtig messen (Verständnisproblem)

    • Andy
    • 13. Dezember 2016 um 13:33
    Zitat von Cape-City

    OK, bei jedem ALR Aufruf pausiert mein Script (meine DO-Schleife), aber es kann ja vorkommen, das ALR 2-3 mal öfters aufgerufen wird, als meine DO-Schleife für einen Durchlauf braucht...

    Dann läuft mit deinem Konzept gewaltig etwas schief!
    Ich nutze die AdlibRegister()-Funktion ausschliesslich, um die FPS ANZUZEIGEN! Das ist innerhalb der Funktion dann maximal ein Ein- bis Dreizeiler. "Pausieren" tut da mal garnichts!

    Nach deinem obigen Script ist es sowieso schon fraglich, ob und wieso die korrekte Anzahl FPS angezeigt werden soll?!
    Wenn du mit mehreren Adlib-Funktionen arbeitest, wird irgendwann der Fall eintreten, dass der Adlib-Timer deine Funktionen "stört".
    Wobei du den FPS bei mehrern Timern nicht brauchst, da sowieso logischerweise nur der "langsamste" Timer gezählt wird!

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™