Frage

Wenn ich die C99 restrict Stichwort Recht, qualifying einen Zeiger mit es ist ein Versprechen, dass die Daten, die es verweist, nicht geändert werden hinter den compiler zurück durch aliasing.

Durch Kontrast, die so verstehe ich das const qualifier ist als die vom compiler erzwungen Dokumentation, die ein bestimmtes Objekt wird nicht geändert werden, hinter dem Rücken eines Menschen code schreiben.Der compiler könnte eine Andeutung als Nebenwirkung, sondern als ein Programmierer, der ich nicht wirklich.

In ähnlicher Weise wäre es angemessen zu erwägen, eines restrict qualifier in einer Funktion, die als Prototyp einer Anforderung, dass der Benutzer garantiert, die exklusiven Zugang ("Vermeidung von aliasing" oder vielleicht etwas stärkeres) für die Dauer des Gesprächs?Sollte es verwendet werden als die "Dokumentation"?

Außerdem gibt es etwas zu verstehen in der Tatsache, dass restrict qualifiziert sich ein Zeiger, anstatt die Daten, die Sie Punkte (wie const es tut) ?

EDIT:Ich hatte ursprünglich angenommen, dass restrict könnte auch Auswirkungen mit Gewinde-code, aber dies scheint falsch, so Entferne ich Verweise auf threads von der Frage zu vermeiden verwirrend Leser.

War es hilfreich?

Lösung

Die beste ‚Intuition‘ über das haben, beschränkt Schlüsselwort ist, dass es eine Garantie (vom Programmierer an die Compiler), dass für die gesamte Lebensdauer des Zeigers über diesen Zeiger zugegriffen Speicher wird nur über diesen Zeiger zugegriffen werden und nicht über einen anderen Zeiger oder eine Referenz oder globale Adresse. So ist es wichtig, dass sie auf einem Zeiger als eine Eigenschaft von sowohl den Zeiger und dem Speicher, die beide zusammen zu binden, bis der Zeiger den Gültigkeitsbereich verlassen.

Andere Tipps

Chris Dodd hat die korrekte Beschreibung des Keywords. In bestimmten Plattformen kann es aus Performance-Gründen sehr wichtig sein, weil es der Compiler wissen lässt, dass, sobald es Daten über diesen Zeiger auf ein Register geladen ist, es nicht wieder tun muss. Ohne diese Garantie muss der Compiler die Daten über einen Zeiger jedes Mal ein anderer möglicherweise Aliasing-Zeiger wird geschrieben durch, lädt die eine ernsthafte Pipeline-Blockierung verursachen kann ein load-hit-store .

const und restrict sind unterschiedliche Konzepte, und es ist nicht der Fall, dass const restrict impliziert. Alle const sagt, ist, dass Sie nicht durch diesen Zeiger im Rahmen dieser Funktion schreiben. Ein const Zeiger kann noch aliased werden. Zum Beispiel betrachten:

int foo( const int *a, int * b )
{
   *b *= 2;
   return *a + *b; // induces LHS: *a must be read back immediately
                   // after write has cleared the store queue
}

Sie können zwar nicht direkt schreiben können in dieser Funktion a, wäre es vollkommen legal für Sie foo nennen wie:

int x = 3;
foo( &x, &x );  // returns 12

restrict ist eine andere Garantie:. Ein Versprechen, das in allen Anrufen a != b foo()

Ich habe geschrieben über die restrict Schlüsselwort und seine Auswirkungen auf die Leistung endlich und

Das meiste, was Sie wissen ist falsch!

const tut nicht Garantie, dass etwas nicht ändern, hinter den compiler zurück.Alle es tut, ist zu stoppen Sie vom schreiben auf die spot.Etwas anderes könnte noch in der Lage sein zu schreiben Sie zu diesem Speicherort, obwohl, so dass der compiler nicht davon ausgehen, es ist konstant.

Wie andere gesagt haben, ist das einschränken der Beiname ist über aliasing.In der Tat, während der ersten Runde der C-Standardisierung war es, einen Vorschlag für eine "noalias" keyword.Leider wurde der Vorschlag ziemlich schlecht geschrieben-es aufgefordert, die einzige Zeit, die Dennis Ritchie geriet während dieser Prozess, wenn er einen Brief schrieb, der sagte etwas zu dem Effekt, dass "noalias gehen muss.Diese ist nicht offen für Verhandlungen."

Unnötig zu sagen, 'noalias' nicht werden, Teil C.Wenn es Zeit kam, um erneut zu versuchen, der Vorschlag wurde genug geschrieben, besser beschränken, wurde in der Norm -- und obwohl noalias hätte wohl einen aussagekräftigeren Namen, der name war so verdorben, dass ich bezweifle, dass irgendjemand, auch als Versuch, es zu verwenden.

In jedem Fall, die primäre Absicht beschränken, zu sagen dem compiler, dass es sich nicht um einen alias zu diesem Artikel.Ein Grund dafür ist es, die Dinge werden in Registern gespeichert vorübergehend.Betrachten Sie zum Beispiel etwas wie:

void f(int *a, int *b, int *c) { 
    for (int i=0; i<*a; i++)
        *b += c[i];
}

Der compiler wirklich setzen will ich in ein register, und laden *ein in ein register, so dass, wenn es darum geht, Zeit, um zu entscheiden, ob zum ausführen einer anderen iteration der Schleife, die es nur vergleicht die Werte in diese Register zu einander.Leider kann es nicht tun-wenn jemand, verwendet diese Funktion war völlig verrückt, und bezeichnet es mit a==b, jedes mal, wenn Sie schreibt zu *b innerhalb der Schleife, der neue Wert ist auch der Wert von *a-also, es zu Lesen hat *eine aus dem Speicher bei jeder iteration der Schleife, nur für den Fall, wer auch immer es genannt wurde, völlig verrückt.Die Verwendung einschränken, sagt der compiler kann code generieren, vorausgesetzt, dass a und b wird immer unterschiedlich sein, so schreiben *eine wird sich nie ändern *b (oder Umgekehrt).

Ihr Verständnis ist weitgehend richtig. Die restrict Qualifier besagt einfach, dass die durch einen so qualifizierten Zeiger zugegriffen Daten nur von genau dieser Zeiger abgerufen. Es gilt für liest als Brunnen als schreibt.

Der Compiler kümmert sich nicht um gleichzeitige Threads, war es anders nicht geht Code zu generieren, und Sie können Ihre eigenen Daten verprügeln, wie Sie möchten. Aber es muss wissen, welche Zeigeroperationen ändern können, was den globalen Speicher.

Restrict trägt auch mit ihm eine API-Warnung für die Menschen, die eine gegebene Funktion mit der Annahme unaliased Parameter durchgeführt wird.

Keine Sperren durch den Benutzer notwendig ist, so weit wie der Compiler geht. Sie will nur sicherstellen, dass es richtig Daten liest, die war sollte von Code verprügelt, wird die Compiler generieren sollte , falls es kein restrict Qualifier. Hinzufügen restrict befreit es von dieser Sorge.

Schließlich ist zu beachten, dass der Compiler wahrscheinlich ist bereits möglich Aliasing auf Datentypen anhand der Analyse sein, bei den höheren Optimierungsstufen, so restrict ist wichtig, vor allem für Funktionen mit mehreren Zeigern auf die gleiche Art von Daten. Sie können eine Lehre aus diesem Thema nehmen und stellen Sie sicher, dass jede vorsätzliche Aliasing Sie über eine union erfolgt tun.

Wir können restrict in Aktion sehen:

void move(int *a, int *b) {     void move(int *__restrict a, int *__restrict b) {
    a[0] = b[0];                    a[0] = b[0];
    a[1] = b[0];                    a[1] = b[0];
}                               }
    movl    (%edx), %eax            movl    (%edx), %edx
    movl    %eax, (%ecx)            movl    %edx, (%eax)
    movl    (%edx), %eax            movl    %edx, 4(%eax)
    movl    %eax, 4(%ecx)

In der rechten Spalte, mit restrict, der Compiler nicht brauchte b[0] aus dem Speicher neu zu lesen. Es war in der Lage b[0] und halten Sie sie im Register %edx zu lesen, und speichern Sie dann nur das Register zweimal in dem Speicher. In der linken Spalte, wußte es nicht, wenn der Laden zu a hat b geändert werden.

Jemand vertrauter mit dem Standard wahrscheinlich eine bessere Antwort geben könnte, aber ich werde es ein Schuss.

„Die Daten werden nicht hinter dem Rücken des Compiler modifiziert werden“ klingt wie das Gegenteil von „flüchtig“ zu mir.

„const“ bedeutet, dass die Daten nicht vor dem Programmierer verändert werden; das heißt, sie kann nicht die Daten über die Signifikanten ändern als „const“ markiert (ich schreibe „Signifikant“, weil in int const *pi, wird der Name pi nicht const, aber *pi ist). Die Daten könnten über einen anderen Signifikanten modifizierbar sein (nicht konstante Daten können auf eine Funktion als const Daten weitergegeben werden, nachdem alle).

Der „beschränken“ qualifiziert Zeiger ist der Schlüssel. Zeiger sind der einzige Weg, um Alias-Daten in C, so dass sie die einzige Möglichkeit, dass Sie einig Stück von Daten über zwei verschiedene Namen zugreifen können. „Beschränkt“ dreht sich alles um den Datenzugriff auf einen Zugriffspfad zu begrenzen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top