2009-08-19 10 views
1

Ich verschiebe meine C++ - Codebasis von Visual Studio 2k3 nach Visual Studio 2k8. Code enthältWie portiere ich Code, der #pragma enthält, optimieren ("a") von VC++ 7 zu VC++ 9?

#pragma optimize("a", on) 

MSDN says, dass es bedeutet "kein Aliasing übernehmen". Spätere Versionen von VS weigern sich, dies zu kompilieren und MSDN scheint nicht zu sagen, was mit Code zu tun ist, der dieses #pragma enthält.

Was bedeutet "kein Aliasing annehmen" und wie kann ich eine Entscheidung treffen, was ich mit dieser Codezeile machen soll?

Antwort

5

Aliasing ist, wenn man Sachen wie diese haben:

int a[100]; 

int * p1 = &a[50]; 
int * p2 = &a[52]; 

nun ein, P1 und P2 sind alle Aliase für das Array, oder Teile davon. Diese Situation kann verhindern, dass der Compiler optimalen Array-Zugriffscode erzeugt (FORTRAN verbietet dies, weshalb es mit der Array-Leistung so gut ist).

Das Pragma, über das Sie nachfragen, besagt, dass der Compiler davon ausgehen kann, dass die obige Situation nicht existiert. Natürlich, wenn Sie müssen entscheiden, ob Sie brauchen diese Sie eines von zwei Dingen tun:

  • Scheck den gesamten Code (schwierig und fehleranfällig)
  • schalten ihn ab und sehen, ob es irgendwelche Leistungsverschlechterungen ist (leicht und sinnvoll)

die Wahl :-)

+0

Ich verstehe wirklich nicht, wie die oben genannten Sachen verhindern, dass der Compiler schneller Code erzeugt. – sharptooth

+2

Es geht darum, welche Werte der Compiler in Registern cachen kann - ein bisschen wie das volatile Problem. –

+2

@sharptooth: Der Compiler weiß nicht immer über das Aliasing - z.B. wenn a, p1 und p2 in eine Funktion übergeben werden. Ohne "kein Aliasing annehmen" würde eine Modifikation durch p1 alle zwischengespeicherten Daten über a und p2 ungültig machen, was Speicherlesevorgänge statt Registerleseoperationen erfordern würde. – peterchen

0

MSDN das Aliasing wie die Verwendung von mehreren Namen definieren, die auf die gleiche Speicherstelle beziehen.

Die Richtlinie #pragma, die zur Steuerung dieser Optimierung in VS.NET verwendet wurde, ist seit VS.2005 verschwunden.

Es scheint, dass die __restrict Schlüsselwort und restrict und noalias__declspec Modifikatoren verwendeten Variablen und Funktionen zu annotieren, könnte die gleiche Arbeit tun.

2

Hinzufügen zu dem, was Neil sagte:

Mit dem Pragma Sie eine Garantie für den Compiler zu machen, die Aliasing-nto auftritt, so dass additonal Optimierungen, die nicht möglich, „Standard“ Code sind.

Zum Port: Entfernen Sie das Pragma, vergleichen Sie dann die Laufzeit des VC7 und VC9 Build. Wenn der VC9-Build ordnungsgemäß funktioniert, sind Sie fertig.

Andernfalls, wenn der VC9-Build wesentlich langsamer ist, vergleichen Sie den VC7-Build ohne die #pragma zum VC9-Build. Wenn die zusätzlichen Optimierungen die Ursache der Geschwindigkeitsdifferenz sind, sollte der VC7-Build nun auf den VC9-Build verlangsamt werden.

Wenn das der Fall ist, schauen Sie in die __restrict/__declspec(noalias) Deklarationen, und insbesondere die nicht-Alias-Verweise in dem betroffenen Codeblock. Verwenden Sie einen Profiler, um die Unterschiede zwischen dem Code zu finden.

Ansonsten ist die Geschwindigkeitsdifferenz nicht mit der # Pragma verwandt.

+0

Natürlich, ob restrict/noalias eine gute Idee ist oder nicht, ist ein berühmter Streitpunkt, Dennis Ritchie war heftig dagegen - siehe http://www.lysator.liu.se/c/dmr-on-noalias. html –

+0

@Neil: danke für den Link - interessant zu lesen. Ich habe nicht erwartet, dass Noalias als Typ-Qualifier agieren (was schon jetzt beängstigend klingt). – peterchen

+0

Weiß jemand wie sehr die Noalias DMR sprechen - zum Zeitpunkt der Normalisierung von * C89 * wurde Noalias nicht in C89 geschrieben - ist das in C99 eingeführte Restricted anders? – AProgrammer