Guten Tag in die Runde, ich bin ein absoluter Anfänger in Sachen Compiler und deren Anwendung. Vielleicht kann mir hier jemand weiter helfen. Die umfangreichen Quelldateien liegen mir vor. Ich möchte daraus für unterschiedliche Targets die Exe Datei erstellen, z.B. x64 (ist bereits im Compiler vorhanden), als auch AVX, SSSE3, BMI etc. pp. Wo finde ich die Targets? Und Wie installiere ich die Targets?
Unter Windoof ist kein Compiler im Lieferumfang - Du musst uns auch mitteilen welchen Compiler Du benutzen möchtest. Bin wohl blind, MSVC2022 ist im Titel. Sorry. Da kann man das in den Compiler und Linker Optionen einstellen. Unterschiedliche Exe zu erstellen ist nicht gänzlich ohne, aber die IDE erstellt normalerweise bereits ein Debug und ein Release Build die man als Beispiel ansehen wie man Compiler und Linker Optionen einstellen kann.
:
Bearbeitet durch User
Esmeralda P. schrieb: > z.B. x64 (ist bereits im Compiler vorhanden), als auch AVX, SSSE3, Mach dich erstmal schlau, was das ist, was du da hingeschrieben hast! x64 macht noch halbwegs sinn, AVX und SSE3 sind was ganz anderes, und vorallem keine Targets für die man compiliert...
Kaj G. schrieb: > AVX und SSE3 sind was ganz anderes, und > vorallem keine Targets für die man compiliert... Das kommt durchaus drauf an. Ist nur eine Frage der Spezifikation der Software. Wenn darin steht, dass sie zum Lauf halt AVX oder SSE3 benötigt, dann ist es absolut legitim, eine entsprechendes Programm zu kompilieren (welches dann halt keine Fallbacks für den Fall der Nichtverfügbarkeit enthalten muss). Was man aber auch bei einem solchen Programm immer einbauen sollte: Eine Laufzeitprüfung, ob die spezifizierten Anforderungen erfüllt sind. Und die sollte bei negativem Ergebnis sowohl eine aussagekräftige Fehlermeldung liefern, was genau fehlt als auch einen geordneten Exit des Programms bewerkstelligen. An dieser simplen und überaus nützlichen Sache scheitern leider viele "Programmierer"...
Esmeralda P. schrieb: > Die umfangreichen Quelldateien liegen mir vor. Vom Visual Studio? Und was glaubst Du sonst noch so?
Harald K. schrieb: > Esmeralda P. schrieb: >> Die umfangreichen Quelldateien liegen mir vor. > > Vom Visual Studio? Und was glaubst Du sonst noch so? Die Quellen kommen natürlich nicht vom VS, sollen sich aber wohl damit übersetzen lassen. Was wohl fehlt, sind die Metadaten für die verschiedenen Build-Targets. Deren Details liegen beim VS in den Projektdateien. Und in der Solution-Datei gibt es eine Liste der möglichen Targets. Also entweder beschafft "Esmeralda" (wohl nur ein unfähiger und mit einiger Wahrscheinlichkeit männlicher Programmierer) neben den eigentlichen Quellen auch noch diese Metadaten oder er/sie/es muss das halt selber konfigurieren. Das kann man mit einem simplen Texteditor direkt in den entspechenden Dateien tun oder auch in dem GUI, welches die IDE dafür bereitstellt. That's all.
Kaj G. schrieb: > Esmeralda P. schrieb: >> z.B. x64 (ist bereits im Compiler vorhanden), als auch AVX, SSSE3, > Mach dich erstmal schlau, was das ist, was du da hingeschrieben hast! > x64 macht noch halbwegs sinn, AVX und SSE3 sind was ganz anderes, und > vorallem keine Targets für die man compiliert... Du hastvöllig recht mit deiner Aussage, habe mich falsch ausgedrückt. Aber Du weißt warum es mmir geht?
C-hater schrieb: > Kaj G. schrieb: > >> AVX und SSE3 sind was ganz anderes, und >> vorallem keine Targets für die man compiliert... > > Das kommt durchaus drauf an. Ist nur eine Frage der Spezifikation der > Software. Wenn darin steht, dass sie zum Lauf halt AVX oder SSE3 > benötigt, dann ist es absolut legitim, eine entsprechendes Programm zu > kompilieren (welches dann halt keine Fallbacks für den Fall der > Nichtverfügbarkeit enthalten muss). Das würde ich trotzdem nicht als eigenes Target bezeichnen, sondern eher als eine Optimierungs-Option, die bestimmte CPU-Erweiterungen erfordert. > Was man aber auch bei einem solchen Programm immer einbauen sollte: Eine > Laufzeitprüfung, ob die spezifizierten Anforderungen erfüllt sind. Und > die sollte bei negativem Ergebnis sowohl eine aussagekräftige > Fehlermeldung liefern, was genau fehlt als auch einen geordneten Exit > des Programms bewerkstelligen. Oder automatisch auf eine Version zurückfallen, die das nicht benötigt.
<senfbecher-auf> "Target" ist schon nicht so falsch... Wenn man in den Projekteinstellungen (also global) meinetwegen AVX2 festlegt, dann kann es schon in main, WinMain oder DllMain knallen (Illegal Instruction), wenn die ausführende CPU kein AVX2 unterstützt und der Compiler halt schon dort angefangen hat mit AVX2-Befehlen zu hantieren. Das geht schneller, als man denkt. Es ist also durchaus ratsam, nicht das komplette Projekt mit AVX2 zu kompilieren, sondern erstmal auf CPU-spezifische Dinge zu verzichten. Dann wird nur SSE2 genommen, was unter Win64 immer vorhanden ist. Einzelne (zeitkritische) Funktionen oder größere Programmteile kann man dann mit "Multi-Versioning" optimieren lassen. Für den clang-Compiler, den man ja im VS2022 problemlos nachinstallieren kann (und auch sollte, da er besser als der MS-Compiler optimiert), geht das so wie hier beschrieben: https://clang.llvm.org/docs/AttributeReference.html#target Der Compiler macht dann den Rest und zur Laufzeit wird die zur CPU passende Funktion aufgerufen. Man kann das natürlich auch händisch erledigen und schreibt für CLANG das "Target-Attribut" direkt über den Funktionsbody.
1 | //__attribute__((target("sse2")))
|
2 | int MachWasMitSSE2 (double* pin, double* pout, int numElements){ |
3 | ...
|
4 | }
|
5 | __attribute__((target("avx"))) |
6 | int MachWasMitAVX (double* pin, double* pout, int numElements){ |
7 | ...
|
8 | }
|
9 | |
10 | __attribute__((target("avx2"))) |
11 | int MachWasMitAVX2 (double* pin, double* pout, int numElements){ |
12 | ...
|
13 | }
|
14 | __attribute__((target("avx512f, avx512bw, avx512vl"))) |
15 | int MachWasMitAVX512 (double* pin, double* pout, int numElements){ |
16 | ...
|
17 | }
|
Jetzt braucht man beim Programmstart nur noch einen CPU-Check (z.B. IsProcessorFeaturePresent) und etwas Code, der dafür sorgt, daß die Adresse der zur CPU passenden MachWas-Funktion in den "MachWasFunktionPointer" geschrieben wird.
1 | typedef int pfnMachwas(double*, double*, int); |
2 | pfnMachwas *MachWasFunktionPointer = MachWasMitSSE2; //default SSE2 |
Der SSE2-Code ruft dann später ganz normal MachWas() auf - und alles ist gut.
1 | int MachWas (double* pin, double* pout, int numElements){ |
2 | return MachWasFunktionPointer(pin, pout, numElements); |
3 | }
|
<senfbecher-zu> PS: Hatte gerade etwas Langeweile...
:
Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.