MSDN TechTalk – <<Monat JJJJ>> <<Thema>> 1

Slides:



Advertisements
Ähnliche Präsentationen
Star Trek 11: Unendliche Weiten Wissenschafliche Software mit .NET
Advertisements

C Sharp (C#) Martin Saternus Senior Student Partner
Imperative Programmierung
der Universität Oldenburg
DVG Einfache Klassen Einfache Klassen. DVG Einfache Klassen 2 Strukturen Beispiel: Personendaten bestehen aus –String name –String vorname.
SQL Server 2005.NET Integration Sebastian Weber Developer Evangelist Microsoft Deutschland GmbH.
Migration und Nutzung von vorhandenem Code Interoperability.
Was ist neu in VS 2003 ? Ein Überblick. Bernd Marquardt Software & Consulting
Microsoft Academic Program C# 2.0 Was gibts da Neues? Student Technology Conference 2005.
Kapselung , toString , equals , Java API
6. Der OpenMP Standard Direktiven-basiertes API zur Programmierung von Parallelrechnern mit gemeinsamem Speicher für FORTRAN, C und C++
der Universität Oldenburg
Spec# Proseminar Assertions im SS 2007 Uni Paderborn Andreas Martens Betreuer: Dipl. Inform. Björn Metzler.
Ausnahmen HS Merseburg (FH) WS 06/07.
Java: Objektorientierte Programmierung
Java: Dynamische Datentypen
Indirekte Adressierung
Java: Grundlagen der Sprache
Java: Referenzen und Zeichenketten
Java: Grundlagen der Objektorientierung
Strukturen. In einer Struktur kann eine beliebige Anzahl von Komponenten (Daten) mit unterschiedlichen Datentypen (im Gegensatz zu Feldern) zusammengefaßt.
Klassenvariable. Da man für jede Kuh bzw. jede Henne auf dem Markt den gleichen Preis für ein Liter Milch, bzw. den gleichen Preis für ein Ei bekommt,
Konstruktoren.
Polymorphie (Vielgestaltigkeit)
Objekte und Arbeitsspeicher
Dynamischer Speicher. In einer Funktion wird z.B. mit der Deklaration int i; Speicher auf dem sogenannten Stack reserviert. Wenn die Funktion verlassen.
OpenMP Präsentation im Rahmen des Seminars
Praktikum Entwicklung und Einsatz von Geosoftware I - Sitzung 3 Klassen, Objekte, Arrays und Kontrollstrukturen Sommersemester 2003 Lars Bernard.
Programmieren mit JAVA
Programmieren mit JAVA
PKJ 2005/1 Stefan Dissmann Zusammenfassung Bisher im Kurs erarbeitete Konzepte(1): Umgang mit einfachen Datentypen Umgang mit Feldern Umgang mit Referenzen.
Zusammenfassung Vorwoche
Introducing the .NET Framework
Vorlesung, Wintersemester 2009/10M. Schölzel 1 Optimierungstechniken in modernen Compilern Optimierungstechniken für SMP- Architekturen.
Einführung in Visual C++
DVG Kommentare1 Kommentare. DVG Kommentare 2 Kommentare Es gibt zwei Arten von Kommentaren: einzeilige Kommentare // der Kommentar geht.
DVG Klassen und Objekte
DVG Einfache Klassen 1 Einfache Klassen. 2DVG Einfache KlassenStrukturen Beispiel: Personendaten bestehen aus String name String name.
EDV Parallelprogrammierung1 Parallelprogrammierung mit JAVA.
DVG Kommentare 1 Kommentare. 2 Kommentare Es gibt zwei Arten von Kommentaren: einzeilige Kommentare // der Kommentar geht bis zum Ende der Zeile.
Einführung in die Programmierung Datensammlung
Informatik 1 Übung 8. NACHBESPRECHUNG Übung 8 Rekursion Existiert Weg von A nach B?
Einführung in die Programmierung
SQL Server 2005 CLR-Integration
Javakurs FSS 2012 Lehrstuhl Stuckenschmidt
Java Garbage Collection Angelika Kusel, Überblick Was ist Garbage Collection? Vor- und Nachteile von GC GC-Algorithmen/Verfahren Java Garbage.
EPROG Tutorium Einheit 4 Klassen und Objekte. Wiederholung Schleifen do... while while for break/continue Strings String char Methoden für Strings Arrays.
Einführung in die Programmierung Wintersemester 2008/09 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Einführung in die Programmierung Wintersemester 2008/09 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fachbereich.
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fachbereich.
Entwicklung verteilter Anwendungen I, WS 13/14 Prof. Dr. Herrad Schmidt WS 13/14 Kapitel 1 Folie 2 Microsoft.NET Framework: Quelle:
Einführung in die Programmiersprache C 4
Informatik 1 Letzte Übung.
Dynamische Datentypen
Garbage Collection unter .NET
Vortrag: Visual Basic Neuerungen Autor : Dennis Hoyer
EPROG Tutorium #3 Philipp Effenberger
Neuerungen in Java 5/6/7. Stefan Bühler für InfoPoint Überblick Java 5 neue Sprachfeatures Erweiterungen Klassenbibliothek Java 6 Erweiterungen.
JOMP
Parallelisierung für Multiprozessor-Maschinen
Parallele Programmierung im.NET Framework Darmstadt, Präsentation am Beispiel von C-Sharp (C#)  Wichtige Grundlagen  Generika, Delegate, Lambda,
Microsoft Student Partner
Vortrag Einführung in AspectJ. Gliederung 1 Einleitung 2 Querschnittsfunktionalitäten in AspectJ 2.1 Sprachelemente 3 Beispiel 4 Join Point Modell 5 Weaving.
C++ FÜR cOMPUTERSPIELENTWICKLER
Strukturen (Eigenschaften) Strukturen dienen zur Zusammenfassung mehrerer Komponenten verschiedener Typen zu einer Einheit, die dann mit gemeinsamen Namen.
Pointer. * und &  Bei der Definition int var1; ○ // „normale“ Variable int *var2; ○ // Zeiger auf einen Integer int *var2 = NULL; ○ // … incl. Initialisierung.
Konstruktoren.
Implementieren von Klassen
 Präsentation transkript:

MSDN TechTalk – <<Monat JJJJ>> <<Thema>> 1 C++ mit .NET Bernd Marquardt Microsoft Regional Director Germany Software & Consulting berndm@go-sky.de http://www.go-sky.de

Hinweis Ja, es sind viele Slides… …aber einige Slides sind nur der Vollständigkeit halber dabei und werden im Vortrag selbst sehr schnell erledigt! Wir werden nicht alle Demo‘s hier testen… …aber in einer „stillen Stunde“ können Sie die Demo‘s selbst ausprobieren

Agenda Einführung C++ Managed Extensions für .NET Stand der Dinge Anwendung: Wrapper-Klassen Performance C++ in Visual Studio 2005 (Whidbey) CLI Generische Typen, STL und … OpenMP Zusammenfassung 2003 2005

Einführung C und C++ sind wichtige Programmiersprachen unter Windows Bis 1992 in „reinem“ C und SDK Danach mit C++ und MFC Windows „begann“ mit C VB kann erst später Bei Microsoft wird auch heute noch FAST alles mit C++ codiert Das soll aber in Zukunft anders werden

Einführung Vorteile von C++: Nachteile von C++: Performant Volle Kontrolle, man kann alles machen Wenig zu tippen Es geht immer alles, was möglich ist Nachteile von C++: Schwer zu lernen Viele Fallstricke und „Pumpen, vor die man laufen kann“

Einführung Die „Pumpen“ von C und C++ Zeiger Makros – das „Klammerproblem“ new / delete switch / break Globale Variablen und Funktionen Variablen-Initialisierung …

C++ und .NET: Heute C++ Managed Extensions Aufruf von unmanaged Code Zugriff auf das .NET-Framework Aufruf von unmanaged Code Wrapper-Klassen Wrappen von MFC-Klassen

C++ Man. Ext. für .NET C++ Managed Extensions (VS 2002 und 2003): Code sieht nicht sehr schön aus Code ist schwer zu lesen Unterscheidung von „managed“ und „unmanaged“ Objekten ist schwierig Die _-Taste geht sehr schnell kaputt  Managed Extensions sind dem C++ „aufgedrückt“ worden VS 2002: Kein Designer für Windows Forms mit man. C++ enthalten

IL und nativer Code cpptest.cpp void ManagedFunc() {} #pragma unmanaged void NativeFunc() {} #pragma managed void AnotherManagedFunc() {} cpptest.cpp C:>CL.EXE /LD /clr cpptest.cpp C:>ILDASM.EXE cpptest.dll

IL und nativer Code #pragma unmanaged void NativeFunc() {} #pragma managed void ManagedFunc() { NativeFunc(); }

Definition von .NET Typen __gc class ManagedClass {}; __gc struct ManagedClass2 {}; __gc __interface ManagedInterface {}; __delegate void ManagedDelegate(); referenzierende Typen __value class ManagedValueType {}; __value struct ManagedValueType2 {}; __value enum ManagedEnum {}; Wertetypen

Referenzierende Typen Instanzierung durch expliziten __gc new Aufruf Speicher wird auf dem "Managed Heap" angelegt Garbage Collector gibt Speicher für Instanzen wieder frei Variablen grundsätzlich Zeigertypen (__gc*) oder Referenztypen (__gc&) GC kontrolliert __gc* und __gc&

Wertetypen Sind grundsätzlich immer in "etwas" enthalten… …als globale Variable in der Anwendungsdomäne …als lokale Variable im Stackframe …als Feld eines Typs in einer Instanz dieses Typs Instanziierung und Lebenszeit an enthaltende Entität gebunden Die Lebenszeit also ist inkompatibel zur Lebenszeit von .NET-Objekten

Schnittstellen implizite Implementierung explizite Implementierung __gc __interface I1 { void M1(); void M2(); }; __gc class ManagedClass : public I1 public: void M1 {} void I1::M2() {} implizite Implementierung explizite Implementierung

Enumeratoren // C++ Managed Extensions [System::Flags] __value public enum ManagedEnum : short { red = 1 << 0, // 1 yellow = 1 << 1, // 2 blue = 1 << 2 // 4 };

Delegates public __delegate void ADelegate(); ADelegate* pD1 = new ADelegate(pRefToClassXInstance, &ClassX::NonStaticMethod); pD1->Invoke(); ADelegate* pD2 = new ADelegate(0, &ClassX::StaticMethod); pD2->Invoke();

Methoden C++ C# using namespace System; using namespace System::Runtime::InteropServices; public __gc __interface ITest { void M1(Int32 n, String* ps); void M2(Int32* pn, String** ppstr); void M3([Out]Int32* pn, [Out] String** ppstr); }; using Systen; public interface ITest { void M1(Int32 n, String ps); void M2(ref Int32 pn, ref String ppstr); void M3(out Int32 pn, out Int32 ppstr); } C#

Eigenschaften C++ C# public __gc class Test { int _age; public: __property int get_Age() { return _age; } __property void set_Age(int age) { _age = age; } } C++ pTest->Age = pTest->Age + 1; public class Test { private int _age; public int Age get {return _age;} set {_age = value;} } C# test.Age = test.Age + 1;

Indexer C++ C# using namespace System; using namespace System::Reflection; public __gc __interface INameList { __property String* get_Name(int i); __property void set_Name(int i, String* psNewVal); }; C++ INameList* pNL = ...; string str = pNL->Name[0]; using System; public interface INameList { String this[int i] { get; set; } } C# INameList nl = ...; string str = nl[0];

Exception Handling Syntax ist ähnlich wie im klassischen C++ Managed Exceptions sind Referenzen auf beliebige .NET-Objekte Basisklasse System::Exception Verschiedene catch-Blöcke eines try-Blocks können sowohl C++-Exceptions als auch .NET- Exceptions behandeln C++-Exceptions müssen vor .NET-Exceptions behandelt werden Auslösen und Abfangen von C++ und .NET-Exceptions in einer try-Anweisung ist zulässig Win32 Structured Exception Handling (__try, __except) ist in Managed Code unzulässig

Exceptions void ManagedFunc(int i) { try ... } // C++ Exception catch (int i) { System::Console::WriteLine(i); } // nicht CLS kompatible .NET Exception catch (System::Exception* pE) { System::Console::WriteLine(pE->Message); } // CLS kompatible .NET Exception catch (System::Object* pE) { System::Console::WriteLine(pE); } __finally { ... Ressourcen hier freigeben ... }

Determin. Finalisierung C++-Klassen werden als lokale Variablen automatisch deterministisch finalisiert Der Destruktor wird beim Verlassen des Scope aufgerufen… …auch wenn der Scope durch eine Exception verlassen wird Instanzen von .NET Klassen werden nicht automatisch deterministisch finalisiert Die deterministische Finalisierung muss manuell durch try/__finally-Blöcke realisiert werden

Determin. Finalisierung In GC-Klasse kann ein Destruktor implementiert werden Überschreibt Object::Finalize und implementiert Methode __dtor Finalize wird von Garbage Collector aufgerufen, bevor Objekt zerstört wird __dtor wird vom delete-Operator aufgerufen __dtor ruft zuerst GC::SuppressFinalize und dann Finalize auf

Aufruf von unman. Code Demo 1+2 Demo 3 Es gibt sehr viel Code in C und C++ Vieles davon kann man weiter verwenden Aufruf von unmanaged Code: [DllImportAttribute(…)] (geht mit allen .NET-Sprachen) Daten werden automatisch konvertiert Achtung: Anwendung von Zeigern „It just works“-Methode (geht nur mit C++) Einfach die Header-Dateien einfügen und API‘s aufrufen Daten müssen konvertiert werden Demo 1+2 Demo 3

C++ als .NET Sprache Vorteile Nachteile Ermöglicht das Mischen von MSIL-Code und nativem Code Aufruf nativer Funktionen im MSIL-Code ist: …viel einfacher …viel schneller …ohne Einschränkungen möglich Nachteile „Kranke“ Syntax

Wrapper-Klassen Managed Wrapper-Klassen umhüllen eine normale unmanaged C++-Klasse Die Hüllklasse funktioniert wie ein Proxy Die Hüllklasse hat die gleiche Funktionalität wie die C++-Klasse Es wird immer ein „Klassenpaar“ erzeugt, bzw. zerstört Beide Klassen können in einer Datei angelegt werden Einfache Verwaltung

Wrapper-Klassen Ein Objekt der Wrapper-Klasse kann unter .NET wie ein normales .NET-Objekt benutzt werden Die Daten-Konvertierung wird ggf. in der Wrapper-Klasse implementiert Byte, int, long, short, float, double keine Konvertierung nötig String muss konvertiert werden Achtung: ANSI oder UNICODE beachten Struct‘s müssen meistens angepasst werden Es gibt dafür spezielle Attribute (z.B. FieldOffset)

Wrapper-Klassen class CppClass { public: // Konstruktor CppClass() { …} // Destruktor ~CppClass() { // Methoden void native_f() { }; __gc class ManClass { public: // Konstruktor ManClass() { m_pC = new CppClass(); } // Freigabe ~ManClass() { delete m_pC; // Methoden void managed_f() { m_pC->native_f(); private: CppClass * m_pC; };

Wrapper-Klassen Erzeugung einer man. C++-Klasse Data Member in der Wrapper-Klasse: Zeiger vom Typ der C++-Klasse In der managed Klasse müssen die Konstruktoren nachgebildet werden In der Dispose-Methode der managed Klasse die Instanz der unmanaged Klasse zerstören ACHTUNG: Wrapper-Objekt steht unter der Kontrolle des Garbage Collectors Alle public-Methoden der unmanaged Klasse in der managed Klasse implementieren

Wrapper-Klassen Demo 4+5+6 Destruktoren Sowohl den Destruktor als auch die Dispose-Methode implementieren Wrapper-Klasse von IDisposable ableiten „Selbst-gesteuertes“ Zerstören des Objektes durch Dispose-Aufruf Dort Finalize() aufrufen GC::Supress::Finalize wird automatisch vor dem Finalize()-Aufruf getätigt Dispose-Aufruf vergessen: Garbage Collector schlägt mit dem Destruktor zu Demo 4+5+6

Probleme mit Wrappern Variable Parameteranzahl Daten-Marshaling Default Argumente Destruktoren (Garbage Collector) Properties Überladen von Operatoren Wenn der Wrapper z.B. mit VB oder C# genutzt werden soll, müssen die überladenen Methoden auch als “echte” Methode implementiert werden C#: Operator-Overloading erlaubt VB: nicht erlaubt

Wrapper-Klassen Wrapper sind eine einfache Möglichkeit, um existierende C++-Klassen weiter zu benutzen Innerhalb der unmanaged C++-Klassen ist alles erlaubt (z.B.: Multiple Inheritance) Wertet die C++-Klassen auf, da sie nun aus allen .NET-Sprachen aufgerufen werden können Performance beachten Kontext-Wechsel, Konvertierungen

MFC-Dialoge wrappen Anwendung von Wrapper-Klassen Frage: Kann man von alten monolitischen MFC-Applikationen irgendetwas weiter verwenden (mit Hilfe von Wrappern)?

Analyse In Dialogen steckt oft ähnlich viel Code wie im Hauptfenster Ausnahme: Applikationen mit vielen mathematischen Rechenalgorithmen Dialoge sind aufwändig zu erstellen Platzierung der Controls (zeitaufwändig: Design) Programmierung (zeitaufwändig: Tests) Es wäre gut, wenn man die Dialoge weiter verwenden könnte  Wrapper-Klassen!!!

Der Migrationsweg (1) Alle Dialoge in einer MFC-DLL ablegen CPP- und H-Dateien ins DLL-Projekt einfügen Resource.h hinzufügen (kopieren) RC-Datei aus Applikation mit Notepad editieren Nur Dialoge übernehmen Drag&Drop in der IDE klappt (manchmal) irgendwie nicht so ganz

Der Migrationsweg (2) Für jeden Dialog eine Wrapper-Klasse generieren Automatische Erzeugung mit einem kleinen Tool (ist möglich) Unicode / ANSI auswählen Wrapper kann auch von Hand erzeugt werden Manchmal muss die Typ-Konvertierung „von Hand“ implementiert werden „#pragma managed“ und „#pragma unmanaged“ korrekt verwenden

Der Migrationsweg (3) DLL Kompilieren Hauptfenster mit .NET erzeugen „Use managed extensions“ auf „YES“ setzen MFC-Library STATISCH linken (WICHTIG) Hauptfenster mit .NET erzeugen Referenz auf DLL anlegen Menü, Toolbar und Statuszeile (usw.) implemetieren Entsprechende Wrapper-Objekte aufrufen Übersetzen und testen

GenMFCWrapper+DlgDLL1 Der Migrationsweg (4) Deutliche Zeiteinsparung beim Umstieg auf .NET Kein Programmieren und Testen der Dialoge Kein Neu-Design der Dialoge (das kann auch ein Nachteil sein!  Design) Wrapper evtl. mit Tool generieren Demo 7+8+DlgDLL GenMFCWrapper+DlgDLL1

Performance Ein Hauptgrund für C und C++: Auch unter .NET ist C++ sehr schnell Im Moment: Die schnellste .NET-Sprache Wichtig bei mathematischen Berechnungen (Algorithmen) Weniger wichtig bei User Interfaces, mehrschichtigen Datenbank-Applikationen Flaschenhals hier: Datenbank und/oder Netzwerk

Arithmetik (einfach) ((double) i + (double) j) * 2.5 VB 6.0 50.610 sek VC++ 6.0 5.860 sek VC .NET unmng. 5.703 sek VC .NET mng. 7.235 sek C# 8.563 sek VB .NET 9.250 sek VS 6.0 Asm. VS .NET CLR

Arithmetik (kompliziert!) (((double) i + (double) j) * 2.5) / (i + j + 1) VB 6.0 80.313 sek VC++ 6.0 24.891 sek VC .NET unmng. 24.890 sek VC .NET mng. 24.850 sek C# 24.891 sek VB .NET 24.990 sek VS 6.0 Asm. VS .NET CLR

Arithmetik (esotherisch!) Fast Fourier Transformation Sägezahn aus 65.536 Einzelwerten Daten-Array als lokale Variable VC++ unmng. (lok. Array) 63 msek VC++ mng. (lok. Array) 63 msek Mathematische Algorithmen sind sehr schnell – Rechnenoperationen ohne Einschränkungen

Arithmetik (esotherisch!) Fast Fourier Transformation Sägezahn aus 1.048.576 Einzelwerten Daten-Array auf dem Heap (mit VC.NET unter Kontrolle des Garbage Collectors) VC++ unmng. (nat. Heap) 2.250 sek VC++ managed (GC) 2.609 sek Auch mit GC sind (fast so) schnelle Berechnungen möglich

String-Operationen Anhängen von 100.000 Strings zu je 10 Zeichen (Unicode) VB6, normaler String: 44.231 sek Einfacher MFC-String: 17.340 sek MFC-String mit Allokation: 0.046 sek C#, einfacher String: 87.820 sek C#, StringBuilder: 0.047 sek C++, char-Array, memcpy: 0.010 sek

Aufruf von unman. API‘s aus VC++ 6.0 1.500 sek aus C# 4.453 sek Eine herkömmliche Windows-DLL kann von einer Applikation mit managed Code aufgerufen werden Die Funktion erhält double-Wert und gibt einen int-Wert zurück Die Funktion wird 10.000.000 mal aufgerufen aus VC++ 6.0 1.500 sek aus C# 4.453 sek

Weitere Ergebnisse Compilier-Geschwindigkeit des JIT-Compilers Frage: Wieviel Zeit geht bei der „Laufzeit-Übersetzung“ des IL-Codes verloren? JIT kompiliert ca. 5000 Zeilen IL-Code pro Sekunde (500 MHz Pentium III) Geschwindigkeit ist natürlich abhängig vom Code

Optimierung des Codes Es gibt zwei „Stellen“, denen optimiert werden kann Im Sprach-Compiler Im JIT-Compiler Zur Analyse des Maschinencodes Benutzung von: DebugBreak(); Allgemeine Ergebnisse: Manches optimiert der Sprach-Compiler, manches wird vom JIT-Compiler optimiert

Optimierung des Codes for-Schleifen mit wenigen Durchgängen .... d += (double)i1 + 7.5 * 11.2 / 2.5; Sprach-Compiler fasst zusammen for-Schleifen mit wenigen Durchgängen JIT macht Loop-Unrolling for(i = 5; i < 5; i++) JIT beachtet die Schleife nicht d += 3 + a – a; JIT erzeugt keinen Code für „+ a - a“ ....

Warum C++ unter .NET? 1. Performance 2. Volle Kontrolle 3. Es geht alles 4. Einfacher Zugriff auf „alten“ unmanaged Code Compiler für 64-bit-Prozessoren verfügbar

C++ und .NET: Morgen C++ in Visual Studio 2005 (Whidbey) Neue Features mit C++ Optimierungen C++/CLI – Common Language Infrastructure Generische Typen und Templates Multithreading mit OpenMP

C++: Neues in VS 2005 Neue Syntax    Elegant und einfach Natürlich Verifiable Code Keine __keywords Context-sensitive Keywords Wirksam in einem bestimmten Kontext Spaced Keywords Werden zusammen mit anderen Keywords benutzt

Neue Syntax Nachlesen in: C++/CLI Specification http://download.microsoft.com/download/9/9/c/99c65bcd-ac66-482e-8dc1-0e14cd1670cd/C++%20CLI%20Candidate%20Base%20Draft.pdf …schöne URL…

C++ Managed Extensions public __gc __sealed class Student { private: double m_grade; String* m_name; public: // Property implementation __property double get_Grade() { return m_grade; } __property void set_Grade(double newGrade) { m_grade = newGrade); } __property String* get_Name() { return m_name; } __property void set_Name(String* newName) { m_name = newName; } };

C++ / CLI morgen Demo 9 public ref class Student sealed { private: double m_grade; public: // Standard property syntax property double Grade double get() { return m_grade; } void set(double newGrade) { m_grade = newGrade; } } // Trivial property syntax property String^ Name; }; Demo 9

Klassen mit „Adjektiven“ Die Klassen erhalten Eigenschaften class N { /**/ }; // Nativer Typ ref class R { /**/ }; // CLR Referenz-Typ value class V { /**/ }; // CLR Werte-Typ interface class I { /**/ }; // CLR Interface-Klasse enum class E { /**/ }; // CLR Aufzählungs-Typ

Instanzierung Auf dem native Heap: new T Auf dem managed Heap: gcnew T Früher: __nogc Auf dem managed Heap: gcnew T Früher: __gc Auf dem Stack: T t

Objektzerstörung Demo 10 Objekte im Garbage Collector Nicht deterministische Auflösung Mit „gcnew“ Man bekommt ein „Handle“ Objekte auf dem normalen Heap Deterministische Auflösung (delete) Mit „new“ Man bekommt einen Zeiger Objekte auf dem Stack Deterministische Auflösung (Scope) Nur Deklaration Demo 10

Zeiger und Referenzen Demo 11 Zeiger bleiben Zeiger Mit ihren Vor- und Nachteilen In VS 2005 gibt gcnew ein „Handle“ zurück Darstellung durch ein „^“ ( “hat”) Handles sind die Verbindung zu fertigen Objekten im managed Heap Keine Pointer-Arithmetik Keine Konvertierung nach void Tracking reference operator „%“ Pinning Pointer: pin_ptr Demo 11

Roadmap C++/CLI C++/CLI soll standardisiert werden Oktober 2003: Task Group TG5 ISO C++: WG21 Standardisierung: Ende 2004

Update nach C++/CLI __gc class  ref class __gc struct  ref struct __value class  value class __value struct  value struct Default-Konstruktoren aus value classes entfernen __interface class  interface class __interface struct  interface struct

Update nach C++/CLI __abstract  abstract (nach hinten) __sealed  sealed (nach hinten) __property  property __event  event __value enum  enum class __gc*  ^ __pin  pin_ptr new  gcnew 0 oder null  nullptr

Update nach C++/CLI __gc[ ]  array Alle Instanzen von __box entfernen „S“ vor den String-Konstanten entfernen Explizite Deklaration von überladenen Operatoren entfernen __typeof  typeid< > __try_cast  safe_cast Namensraum stdcli::language hinzufügen

Generische Typen C++-Templates Werden zur Übersetzungszeit expandiert Zur Laufzeit können keine neuen Spezialisierungen aufgebaut werden Die CLR weiss nichts über Templates Ein generischer Typ kann nicht Typ-Parameter eines Templates sein  Compile-Time-Spezialisierung der Templates Explizite Spezialisierung erlaubt Verhalten für einen speziellen Typ Partielle Spezialisierung erlaubt Verhalten für spezielle Argumente

Generische Typen Generics Werden zur Laufzeit vom JIT-Compiler expandiert Generische Typen können von allen .NET-Sprachen benutzt werden, egal in welcher Sprache sie erstellt wurden In mehreren Assemblies möglich Der Typ-Parameter darf nicht als Basisklasse für den generischen Datentyp verwendet werden Default-Werte sind nicht erlaubt JITter kann zur Laufzeit in Abhängigkeit vom Typ-Parameter optimieren

Generische Typen generic <typename T> // template <typename T> ref class GenType // ... { // T entsprechend benutzen // ... }; void _tmain() GenType<typ>^ xxx = gcnew GenType<typ>; } Demo 12

STL Demo 12A STL kann nun auch mit dem .NET-Framework benutzt werden Ist optimiert, um mit managed Code und managed Daten zu arbeiten Die gleichen Technologien, die bisher verwendet wurden, können nun mit der CLR benutzt werden Demo 12A

Interop DLL-Aufrufe (P/Invoke) COM-Aufrufe (RCW und CCW) „It just works“  „Interop Technologies“ Das gab es alles auch schon in VS 2003! Übrigens: .NET-Komponenten können auch aus unmanaged Code aufgerufen werden Bestehende Applikation kann einfach erweitert werden Attribut: ClassInterface verwenden

Optimierungen WPO Bessere Pentium 4-Unterstützung Whole Program Optimization Bessere Pentium 4-Unterstützung Bessere Optimierung beim Linken Profile Guided Optimization Ablauf-Szenarien werden beim Linken berücksichtigt

Optimierungen Profile Guided Optimization (POGO) Source Object- Files Compilieren Object- Files Instrumented Image Link Scenarios Instrumented Image Output Profile Data Object- Files Profile Data Optimized Image Link

Optimierungen POGO ermöglicht… Bessere Entscheidungen zum „Inlinen“ von Code Reorganisation von switch- und if-else-Konstrukten Codeblöcke können besser angeordnet werden Weniger Sprünge, weniger Paging Codeteile können mit unterschiedlichen Optimierungsoptionen übersetzt werden

Security In VS 2002: /GS-Schalter In VS 2005: Überprüfung auf „Buffer Overrun“ In VS 2005: /GS ist standardmäßig eingeschaltet Check-Funktion wurde erweitert Kopie der „angreifbaren“ Variablen wird angelegt und ggf. benutzt Über 400 sichere neue Runtime-Funktionen Unsichere Funktionen werden ersetzt Siehe „strsafe.h“

OpenMP Demo 13 OpenMP ist eine einfache Möglichkeit für Multithreading Für Fortran (Intel) Für C++ (Intel, VS 2005) Normales Multithreading: Klasse mit Methode ThreadStart-Objekt anlegen Thread-Objekt anlegen Thread-Methode starten Synchronisierung mit Join() Demo 13

OpenMP Normales Multithreading beinhaltet einen relativ großen Overhead Insbesondere wenn Algorithmen parallelisiert werden sollen In OpenMP: Steuerung der Parallelisierung durch C++-Pragma im Code Z.B.: #pragma omp parallel Steueranweisung stehen direkt im Code Mit nativem und mit managed Code Compiler-Schalter: /OPENMP

OpenMP Es gibt unterschiedliche Arten der Parallelisierung: Parallelisierung von Schleifen Parallelisierung von Code-Regionen Nicht zu vergessen: Synchronisierung Und wie steht‘s mit der Performance?

Schleifen mit OpenMP Demo 14 Schleifen werden auf mehrere Threads automatisch aufgeteilt Anzahl kann angegeben werden oder ist vom System vorgegeben oder wird dynamisch ausgewählt void saxpy(double z[], double a, double x[], double y, int n) { #pragma omp parallel for for(int i = 0; i < n; i++) z[i] = a * x[i] + y; } Demo 14

Schleifen mit OpenMP Serielle Ausführung im Master-Thread Parallele Ausführung Automatische Synchronisierung Serielle Ausführung im Master-Thread

Schleifen mit OpenMP Das Verfahren kann auch zu Problemen führen: void test(double x[], double z[], int n) { #pragma omp parallel for for(int i = 1; i < n; i++) z[i] = x[i] + z[i – 1]; // Fehler!!! }

Schleifen mit OpenMP Häufig braucht man „Reduktionen“ Es gibt mehrere Threads mit eigenen z-Variablen, die dann zum Schluss zum Endergebnis addiert werden double test(double x[], int n) { double z = 0.0; #pragma omp parallel for reduction(+:z) for(int i = 1; i < n; i++) z += x[i]; } return z;

Variablen und Scope Wenn mehrere Threads erzeugt werden, gibt es zwei Variablen-Arten: private: Jeder Thread hat eine eigene Instanz shared: Es gibt nur eine Instanz für alle Threads Laufvariablen von Schleifen sind automatisch „private“ Kann man steuern: #pragma omp parallel for shared(a, b) private(i, j)

Code-Regionen Demo 15 Codeteile können ebenfalls parallel laufen Anzahl der Threads kann angegeben werden oder ist vom System vorgegeben void test() { #pragma omp parallel num_threads(4) Console::WriteLine(„Hallo, TechTalk!“); } Demo 15

Synchronisierung Ist fast immer irgendwo erforderlich, wenn mehrere Threads laufen barrier critical critical(name) atomic Operatoren: + - ++ -- * / & ^ | << >> master flush Runtime-Lock Synchronisierung kostet Zeit!!!

OpenMP-Library Es gibt diverse Runtime-Methoden in der OpenMP-Bibliothek: Max. Anzahl der Threads setzen oder abfragen Anzahl der vorhandenen Prozessoren abfragen Rückgabe einer eindeutigen Thread-Nummer … Demo 16

OpenMP Das hört sich ja sehr einfach an… …es kann aber auch sehr kompliziert werden Das sprengt aber den Rahmen hier! Vorsicht beim Programmieren mit mehreren Threads ist IMMER wichtig Immer die Performance prüfen Immer die Ergebnisse prüfen OpenMP ist gut für Algorithmen OpenMP ist nicht gut für die Parallelisierung von User Interfaces

OpenMP-Performance Demo 17+18+19+20 ACHTUNG: Performance-Tests sind mit Alpha- oder Beta-Versionen immer etwas kritisch!!! Trotzdem: Einige Versuche… …auf Single-Prozessor-Maschine (P4, 2.4 GHz, ohne HyperThreading) …auf Dual-Prozessor-Maschine (P3, 600 MHz) Demo 17+18+19+20

OpenMP-Performance Schleifen-Parallelisierung (Demo16) Innere Schleife Threads ZeitSingle ZeitDual 20,000 4 2.844 sek 9.937 sek 10,000 4 2.284 sek 6.047 sek 5,000 4 2.083 sek 4.047 sek 2,500 4 1.973 sek 3.010 sek 20,000 3 2.583 sek 8.791 sek 20,000 2 2.393 sek 5.953 sek 20,000 1 0.751 sek 9.812 sek 20,000 Ohne 0.631 sek 9.988 sek

OpenMP-Performance Schleife mit Reduktion (Demo17) Schleife Threads ZeitSingle ZeitDual 10,000,000 10 2.494 sek 9.922 sek 10,000,000 6 2.484 sek 9.906 sek 10,000,000 4 2.493 sek 9.937 sek 10,000,000 3 2.473 sek 9.921 sek 10,000,000 2 2.463 sek 9.890 sek 10,000,000 1 2.524 sek 16.219 sek 10,000,000 Ohne 2.444 sek 15.853 sek

OpenMP-Performance Synchronisierung mit „atomic“ oder „critical“ (Demo18 und Demo19) Sync.-Typ Threads ZeitSingle ZeitDual Atomic 4 7.210 sek 27.501 sek Atomic 2 7.200 sek 27.438 sek Atomic 1 7.130 sek 15.609 sek Atomic Ohne 1.242 sek 7.828 sek Critical 4 9.245 sek 77.047 sek Critical 2 9.998 sek 76.344 sek Critical 1 8.482 sek 18.422 sek Critical Ohne 1.242 sek 7.828 sek

Zusammenfassung C++ Managed Extensions sind HEUTE mit Visual Studio 2003 NICHT das Teil der Wahl Umständlich Schwer zu lesen Aber C++ UND .NET kommen wieder C++/CLI Einfachere Syntax Gut lesbar, weniger “__”  Das gesamte .NET-Framework wird unterstützt In Visual Studio 2005 Viele neue Features Optimierungen, OpenMP,… Wichtig im 64-bit-Umfeld

Buch über OpenMP Parallel Programming in OpenMP R. Chandra, L. Dagum, D. Kohr, D. Maydan, J. McDonald, R. Menon Morgen Kaufmann Publishers ISBN: 1-55860-671-8 Ca. 35 $ Bei Amazon.de oder Amazon.com

Demos und Slides http://software.go-sky.de Download unter: http://software.go-sky.de http://www.techtalk-ist-wieder-da.de

MSDN TechTalk – <<Monat JJJJ>> <<Thema>> 91 Fragen? MSDN TechTalk – <<Monat JJJJ>> <<Thema>> 91 Uff...