OpenCl goes AutoIt Update 31.Dezember 2016 Download: //EDIT 31.12.2016 einige kleinere Bugs gefixt an AutoIt Version 3.3.14.0 angepasst (Konstantenbezeichnungen) DEVICES64 um Speichertransferzeiten erweitert volle 64Bit-Unterstützung Hallo zusammen! Um die enorme Rechenpower aktueller CPU´s und Grafikkarten auszunutzen, war AutoIt bisher eher ungeeignet. Von den vielen teuer bezahlten Cores der CPU wurde maximal nur einer benutzt, die Rechenleistung der Grafikkarte kam nur einigen Grafikbibliotheken zugute. Manch einer kam auf die Idee, den ehrwürdigen AutoIt-Interpreter mittels Assembler- bzw. C-Bibliotheken etwas zu beschleunigen... :rock: OpenCl (Open Computing Language) bietet nun die Möglichkeit, die Rechenleistung von CPU, GPU und anderen Prozessoren mittels paralleler Berechnungen und portablem Code Plattformunabhängig auszunutzen! OpenCl ist in den neuen Treibern für Grafikkarten bereits integriert. Die SDK´s enthalten reichlich Beispielcode, weiterhin sind tolle Tools enthalten, Profiler, Kerneldebugger und vieles mehr....vollintegriert ins VisualStudio10! Ich verweise auf folgende Dokumente, die jeweils aktuellen Versionen erscheinen auf den Entwicklerseiten. OpenCL Reference Pages [URL:http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/] Einführung OpenCl auf deutsch [URL:http://knol.google.com/k/computing-with-nvidia-s-cuda-and-opencl#] AMD-SDK [URL:http://developer.amd.com/sdks/AMDAPPSDK/downloads/Pages/default.aspx] Nvidia-SDK [URL:http://developer.nvidia.com/opencl] Spezifikation [URL:http://www.khronos.org/registry/cl/specs/opencl-1.x-latest.pdf] AMD-Guide [URL:http://developer.amd.com/gpu/AMDAPPSDK/assets/AMD_Accelerated_Parallel_Processing_OpenCL_Programming_Guide.pdf] Die SDK´s und Treiber gibt es von allen Prozessorherstellern, aktuelle x86-CPU´s und Grafikkarten von AMD und Nvidia werden natürlich unterstützt. //EDIT 19.August 2012 Intel Opencl_runtime only 2012 [URL:http://registrationcenter.intel.com/irc_nas/2560/intel_sdk_for_ocl_applications_2012_runtime_setup.exe] mehr wird für Intel-Prozessoren nicht gebraucht Die OpenCL-API beinhaltet reichlich Funktionen, ich habe die meisten bereits nach AutoIt portiert, aber eine UDF würde ich das im derzeitigen Zustand nicht nennen. Eher ein Proof of concept. Die 2D-Funktionen sind bereits in der Warteschleife 8o Was macht OpenCL aus? OpenCl lebt von der Parallelisierbarkeit der Algorithmen. Gut parallelisierbar sind z.B. Grafik- und Bildbearbeitungsfunktionen (Filter) oder Sortierfunktionen. Wissenschaftler verwenden bspw. Matrixmultiplikationen, Fouriertransformationen und andere gut parallelisierbare Algorithmen. Jedes gut in viele gleiche Teilstücke zu zerlegende programmtechnische Problem wird von OpenCL profitieren! Dabei verteilt OpenCL selbstständig das Programm auf alle zur Verfügung stehenden Recheneinheiten. Gerade die bis zu mehreren hundert Recheneinheiten auf den Prozessoren der Grafikkarten (GPU) werden ausgenutzt, was gegenüber den CPU´s teilweise immense Geschwindigkeitsvorteile bringt! Nicht umsonst werden in den großen Rechenzentren immer häufiger Grafikkarten zum "crunchen" eingesetzt, die CPU´s dienen größtenteils nur noch dazu, diese Grafikkartencluster zu "füttern". Wie kommt das Programm nun dazu, auf allen Prozessoren (Cores) gleichzeitig zu laufen? Die Threadverwaltung übernimmt glücklicherweise OpenCl, sind mehr Prozessoren verfügbar, werden diese einfach mitbenutzt... Das zentrale Objekt ist der sogenannte "Kernel", ein Programm in C-Syntax, welches während der Laufzeit vom Treiber kompiliert, und dann auf alle Prozessoren verteilt wird. Dieser Kernel ist in der Regel in einer einfachen Textdatei abgespeichert, also völlig Plattformunabhängig und somit portabel! Die SDK´s enthalten reichlich Beispiele (meistens in C++/C#),aber die dort verwendeten Kernel (die *.cl-Dateien) können logischerweise alle auch mit AutoIt verwendet werden! Los gehts mit OpenCL in AutoIt! Wer sich ob der Einfachheit gegenüber den Funktionen in den Beispielprogrammen wundert, ich habe viele API-Funktionsaufrufe in EINFACHEN AutoIt-Funktionen gekapselt. Wer hardcore-optimiert oder spezielle API-Funktionen benötigt, kann natürlich auch die API-Calls benutzen! Die folgenden Beispiele beinhalten zwar einige Erklärungen, aber wer Fragen oder Probleme hat.....wozu ist das Forum da?^^ Problembeschreibungen bitte mit Prozessor/Grafikkarte und dem Consolenausdruck posten! Beispiel1, eine einfache Quadrierung von Floatzahlen (Versteckter Text) Die Funktion _CL_GetDevice() wird verwendet um den Kernel einem bestimmten Gerät (GPU oder CPU) zuzuweisen. Bei _CL_GetDevice("CPU") wird die CPU verwendet, _CL_GetDevice("GPU") benutzt den Prozessor der Grafikkarte. _CL_GetDevice("ALL") sucht die nächstbeste mögliche Hardware. Der extreme Unterschied zwischen Grafikkarte und CPU wird am folgenden Beispiel deutlich. Wenn eure vorhandene Grafikkarte nicht unterstützt wird, macht nix, es werden wenigstens alle Cores der CPU verwendet! Um in den Genuss erhöhterAusführungsgeschwindigkeit durch eine GPU zu kommen, ist eine einfache Einsteiger-Grafikkarte ausreichend. Superteuer muss sie nicht sein, ich habe mir anhand dieser Seite [URL:https://en.bitcoin.it/wiki/Mining_hardware_comparison] ein Modell in der 70€-Klasse ausgesucht, die passt zu meinem 45€-Prozessor, ist aber zwischen 10 und 100x schneller in der Berechnung einiger Kernel! Einige Kernel werden auch auf der CPU (wesentlich) schneller ausgeführt, wieso das so ist, wird sich im Verlauf dieses Threads noch herausstellen... Beispiel 2, der aus dem ASM-Tutorial bekannte Tunnelflug [URL:http://www.autoit.de/index.php?page=Thread&postID=184464#post184464], von mir als Basic-Freak wohl eher dilletantisch in das Kernel-C umgesetzt. Man beachte den auskommentierten Teil am Ende des Scriptes. (Versteckter Text) Besteht bei (von Hand und viel KnowHow und Arbeit) hochoptimiertem Assemblercode (auf der CPU) noch ein gewisser Geschwindigkeitsvorteil gegenüber den gängigen Hochsprachen, wird auf der GPU klar, WO der Hammer hängt! Faktor 10-20 in der Geschwindigkeit, OHNE Optimierung! Das funktioniert allerdings nur bei gut zu parallelisierenden Algorithmen. Und Platz für Optimierungen innerhalb der Kernel ist reichlich vorhanden, bedingt durch die "andere" Struktur der Grafikprozessoren, Speicheranbindungen usw. Da es für alle gängigen Hochsprachen OpenCL-Unterstützung gibt, reduziert sich der Aufwand zum Beschleunigen eines Programms auf das Umschreiben des "Inner Loop" in einen Kernel, um massiv von der Geschwindigkeit von Mehrkernprozessoren bzw. Grafikkarten zu profitieren! Letzes Beispiel: Ein Flug durch die Mandelbrotmenge, diesen Kernel habe ich mir "ausgeliehen" (man muss das Rad nicht immer neu erfinden^^), im Vergleich dazu verweise ich auf den Assemblercode HIER [URL:http://www.autoit.de/index.php?page=Thread&postID=142574#post142574]. (Versteckter Text) Eins möchte ich noch betonen, die Beispiele sind auf "Einfachheit" getrimmt, es ist natürlich vollkommen blödsinnig, eine Grafik mittels OpenCl auf einer Grafikkarte "rendern" zu lassen, um dann diese Grafik in den Hauptspeicher zu transferieren (DAS kostet ca die 100- bis 1000fache Zeit wie das Rendern an sich!!!) und von dort per GDI wieder zur Darstellung an die Grafikkarte zu schicken.... OpenGL ist das Stichwort, die üblichen Verdächtigen hier im Forum werden sicherlich passende Beiträge einbringen :thumbsup: Ich hoffe auf Feedback und einige interessante Vorschläge für Kernel! Viel Spass mit OpenCl! P.S.: Großen Dank an TheShadowAE, Sprenger120 und AspirinJunkie fürs Testen auf den diversen Hardware-Plattformen!!! //EDIT 8. November 2011: Kleine Bugfixes, Log enthält bei Inteltreibern auch ohne Fehler einen Inhalt, Danke an UEZ fürs Testen //EDIT 19.August 2012 Die einige Files sind teilweise angepasst/modifiziert/weiterentwickelt. ab diesem Post [URL:http://www.autoit.de/index.php?page=Thread&postID=261893#post261893] befinden sich die Vergleiche CPU/GPU als Ergebnis der Mandelbrot-Berechnung //EDIT 26. August 2012 Sollte jetzt auch auf 64Bit-Maschinen laufen OpenCl64.au3 ermittelt die vorhandenen Geräte (Devices), mit denen OpenCL-Kernel berechnet werden können. //EDIT 31.Dezember 2016 Funktionen weiter angepasst Damit die Bestimmung des Geräts und die Kompilierung des Kernels nicht so aufwendig sind, habe ich diese in eine Funktion gewrappert. Mit der Funktion _CL_GetDevice() kann man die Wahl des Devices entweder selbst bestimmen per _CL_GetDevice(), dann wird das nächste verfügbare Device verwendet _CL_GetDevice("CPU")verwendet die CPU, GPU die GPU.... In der Console erscheinen in blauer Schrift die verfügbaren Geräte in einem String, z.B. […] die erste Ziffer bezeichnet die Platform (INTEL/AMD/NVIDIA o.a.), die zweite Zahl das dort enthaltene Gerät (Device) Wenn man genau dieses Gerät verwenden möchte, dann sollte man _CL_GetDevice("ALL",Ziffer_Device,Ziffer_Platform) ;angeben;im vorliegenden Beispiel also_CL_GetDevice("ALL",2,1);verwendet das 2. Device von der 1. Platform die 3. Ziffer des Strings vom verfügbaren Device bezeichnet den Typ (GPU/CPU), dann folgt der Name des Geräts, die Device_ID und die Platform_ID Nach dem Aufruf von _CL_GetDevice() muss man nur noch die Kernel-Parameter setzen und den Kernel laufen lassen, s. weitere Beispiele.