restrict (Keyword C)

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
Benutzeravatar
starcow
Establishment
Beiträge: 557
Registriert: 23.04.2003, 17:42
Echter Name: Mischa Schaub
Kontaktdaten:

restrict (Keyword C)

Beitrag von starcow »

Abend zusammen
Bislang dachte ich eigentlich, ich hätte die Funktion des Keywords restrict soweit verstanden, doch nun beschleichen mich einige Zweifel, ob meine Vorstellungen so tatsächlich den Realitäten entsprechen.

Wovon ich bislang ausging
Gegeben seien folgende zwei Beispiele

Code: Alles auswählen

void foo(int *a, int *b)
{
    int x, y;
    x = *a;
    *b = 7;
    y = *a;
    return;
}
In diesem Beispiel kann der Wert von *a nicht zwischengespeichert werden, da der Pointer a und der Pointer b möglicherweise auf den selben Speicherbereich zeigen (pointer aliasing: *b = 7 könnte den Wert von *a verändern). Somit muss Pointer a bei der Anweisung *a tatsächlich jedes mal dereferenziert werden - was durch den Sprung zur entsprechenden Adresse mehr Zeit kosten würde, als den Wert zwischenzuspeichern (Optimierung des Maschinencodes).

Code: Alles auswählen

void foo(int * restrict a, int *b)
{
    int x, y;
    x = *a;
    *b = 7;
    y = *a;
    return;
}
Da wir nun dem Compiler aber mittels dem Keyword restrict versichern, dass der Speicherbereich auf den Pointer a verweist unabhängig ist vom Speicherbereich, auf den Pointer b zeigt, kann der Compiler Optimierungen vornehmen, die er ohne restrict nicht konnte. Denn die Anweisung *b = 7; hat am Wert *a mit Sicherheit nichts verändert.

Stimmt das denn so?
Etwas verunsichert hat mich diesbezüglich "Handmade Hero Day 005" (Casey Muratori) https://youtu.be/w7ay7QXmo_o?si=sRBu0qP7JdY7jz0Z&t=6627.
Zwar geht er mit einem sehr ähnlichen Beispiel auf die Problematik von "pointer aliasing" ein, doch er erwähnt restrict nur beiläufig gegen Ende - und nicht als Lösung des Problems - wovon ich eigentlich dachte, dass es das sei!
Zuletzt geändert von starcow am 07.02.2024, 22:19, insgesamt 2-mal geändert.
Freelancer 3D- und 2D-Grafik
mischaschaub.com
Benutzeravatar
Krishty
Establishment
Beiträge: 8311
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: restrict (Keyword C)

Beitrag von Krishty »

Dein Verständnis ist soweit richtig.

restrict ist keine vollkommene Lösung, sondern eher eine Notlösung. Die Bringschuld liegt nämlich dann bei dir – du versprichst, dass sich die Zeiger nicht überlappen, und du musst auch wirklich drauf aufpassen dass du dieses Versprechen nicht versehentlich brichst. Der Compiler kann es ja meist nicht prüfen (sonst müsstest du ihn nicht händisch aufklären) und dein Programm wird dann auf subtile Art kaputtoptimiert.

Am Rande: Clang/GCC können wesentlich besser mit restrict umgehen als MSVC. Sie geben dir auch Warnungen aus, falls ihnen Aliasing auf Zeigern auffällt, die restrict deklariert sind. Nur in wirklich offensichtlichen Fällen, aber ein paar Fehler hat mir das schon erspart.

Tatsächlich kann die bessere Lösung sein (weil simpler und breiter unterstützt), wichtige Werte by-value zu übergeben, wie Casey das anmerkt. Deshalb ist der weit verbreitete Grundsatz „alles bis Registergröße by-value übergeben; alles darüber by-reference“ auch Irrglaube. Die Situation ist leider sehr kompliziert.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
starcow
Establishment
Beiträge: 557
Registriert: 23.04.2003, 17:42
Echter Name: Mischa Schaub
Kontaktdaten:

Re: restrict (Keyword C)

Beitrag von starcow »

Wiedermal hervorragend erklärt und auf den Punkt gebracht!
Das macht alles Sinn!
Vielen Dank Krishty! :-)
Krishty hat geschrieben: 07.02.2024, 22:00 ... und dein Programm wird dann auf subtile Art kaputtoptimiert.
Aaah, fies!
Freelancer 3D- und 2D-Grafik
mischaschaub.com
Antworten