2016-12-26 1 views
1

Gibt es eine Möglichkeit zu deklarieren, dass eine Variable nicht-Aliasing in clang ist, um mehr Optimierungen zu ermöglichen, wo die Variable verwendet wird?Deklarieren einer Variable ohne Aliasing in Clang?

Ich verstehe restrict kann verwendet werden, um Zeiger als Non-Aliasing zu deklarieren.

Allerdings frage ich mich auch über Variablen, die Zeiger sein können. Ich vermute (vielleicht zu Unrecht), dass der Compiler vorsichtig sein muss, Dinge anzunehmen, die es ihm erlauben, den Wert einer Variablen zwischenzuspeichern, anstatt ihn jedes Mal neu zu laden.

Beispiel:

class Data 
{ 
public: 
    void updateVal() { 
     // Updates m_val with some value each time it's called (value may differ across different calls) 
     ... 
    } 
    int complicatedCalculation() const { 
     return 3 * m_val + 2; 
    } 
    int m_val; 
}; 

class User 
{ 
    User(Data& data) : m_data{data} {} 
    void f() 
    { 
     m_data.updateVal(); 
     for (int i=0; i<1000; ++i) 
      g(); 
    } 
    void g() 
    { 
     // Will the optimizer be able to cache calc's value for use in all the calls to g() from f()? 
     int calc = m_data.complicatedCalculation(); 

     // Do more work 
     ... 
    } 

    Data& m_data; 
}; 

Auch wenn die Antwort auf die Frage in dem Beispielcode „Ja“ ist, kann es nicht auf „Nein“ ändern, wenn der Code war komplizierter (zB Arbeit unter // Do more work ist) , aufgrund einer Möglichkeit, dass ein Zeigerinhalt geändert wird, wo der Zeiger auf m_data.m_val gezeigt haben könnte? Oder ist das etwas, von dem der Compiler annimmt, dass es nie passiert, außer es sieht die Adresse m_val irgendwo im Code?

Wenn es nicht davon ausgehen, dass, oder sogar es tut, aber die Adresse der m_valtut irgendwo zu bekommen genommen (aber wir wissen, dass sein Inhalt nicht geändert werden), dann wäre es schön, die Lage sein, um m_val als "sicher" von Aliasing-Belangen zu markieren, kann angenommen werden, dass sein Wert nicht durch Zeigerzugriff geändert wird.

+0

Suchen Sie nach [restrict] (http://stackoverflow.com/questions/776283/what-does-the-restrict-keyword-mean-in-c)? – Jarod42

+0

Ja, danke. Ich frage mich aber auch über Nicht-Zeiger-Variablen; wird mehr Details geben. – Danra

+0

Weitere Details hinzugefügt. – Danra

Antwort

0

Der Compiler wird ein Register speichern calc in g zuweisen, es sei denn, dass es bestimmt andere heiße Variablen, die in Registern gespeichert wären besser zu werden.

Jetzt, auch wenn calc in einem Register gespeichert ist, muss möglicherweise noch ein Funktionsaufruf an complicatedCalculation und ein Speicherzugriff auf m_val erfolgen. Der Compiler kann complicatedCalculation inline und den Funktionsaufruf beseitigen, aber es kann den Speicherzugriff nicht beseitigen, es sei denn m_val ist effektiv eine Konstante die ganze Zeit.

Was Sie wirklich wollen, ist die Beseitigung der unnötigen Speicherzugriffe auf m_val in der Schleife in f statt in g. Dazu muss der Compiler davon ausgehen, dass g für das Inlining in f in Frage kommt. Nur wenn es inline ist, kann der Compiler die unnötigen Speicherzugriffe eliminieren. Selbst wenn g m_val direkt modifiziert, kann der Compiler calc noch in einem Register zuordnen und modifiziert es entsprechend. Die einzige Einschränkung hier ist, wenn gkann eine Ausnahme auslösen. Wenn eine Ausnahme jemals ausgelöst wird, muss die In-Memory-Version von m_val auf den neuesten Wert aktualisiert werden, bevor die Ausnahme weitergegeben werden darf. Der Compiler muss Code ausgeben, um dies sicherzustellen. Ohne diesen Code muss die In-Memory-Version von m_val in jeder Iteration aktualisiert werden. Ich weiß nicht, welche Version von clang welchen Ansatz verwendet. Sie müssen den generierten Assemblercode untersuchen.

Wenn die Adresse m_value irgendwo im Code steht, kann der Compiler möglicherweise keine Speicherzugriffe darauf löschen. In diesem Fall kann die Verwendung von restrict hilfreich sein. m_value sollte nicht durch einen anderen Zeiger geändert werden, da dies gegen den Standard verstößt und zu undefiniertem Verhalten führt. Es liegt in Ihrer Verantwortung, dies sicherzustellen.

Ich hoffe, dass Sie sich darum kümmern, entweder weil Sie experimentell festgestellt haben, dass dies ein Leistungsengpass im Code ist oder Sie nur neugierig sind, anstatt aus irgendeinem anderen Grund.

Verwandte Themen