質問

restrict の一般的な理解はありますが、細かい点を明確にしたいと思っています。あるバッファーからヌル終了ストリングを読み取り、別のバッファーにURLエンコードされたバージョンを書き出す機能があります。関数には次のシグネチャがあります(現在は restrict なし):

char const *StringUrlEncode(char const *unencoded, 
                            char *encoded,
                            char *encodedEnd);

unencoded は、nullで終わるソース文字列です。宛先バッファーは、 encoded および encodedEnd で表されます。 encoded は、バッファー内の最初の char を指し、< code> encodedEnd は、バッファの 後の最初の文字を指します。つまり、関数は encodedEnd が指す場所-これは、C ++ STL規則に精通している場合の基本的な begin / end イテレータペアです。

この関数に restrict を追加する場合、最初の2つのパラメーターにのみ適用する必要があります。

char const *StringUrlEncode(char const *restrict unencoded, 
                            char *restrict encoded,
                            char *encodedEnd);

または3つのパラメータすべてに追加することで理解できない利点がありますか?

入力バッファーと出力バッファーを restrict にすることで、コンパイラーがオーバーラップしないことを知ることができます。しかし、最後のパラメーター encodedEnd は出力バッファーの終わりをマークするためにのみ使用されるため、 restrict は実際にはコンパイラーの助けにはならないと考えていますここで(関数宣言に不必要なノイズを追加する以外は、それが害を及ぼさないと思いますが)。

役に立ちましたか?

解決

マイクアクトンの記事こちらをお試しください。 Restrictは、使用しないことによるパフォーマンスへの影響と、誤った使用の結果の両方のため、恐ろしいものです。

あなたの場合、3つすべてのポインターに制限を安全に適用できると思われますが、これは同じメモリー領域をエイリアスしないためです。ただし、3番目のポインターで使用しても、パフォーマンス上のメリットはほとんど、またはまったくありません。

他のヒント

この特定のケースでは、 encodedEnd が制限されているかどうかに違いはありません。コンパイラーに unencoded encoded のエイリアスを作成しないことを約束しているため、読み取りと書き込みが相互に干渉しません。

この場合、restrictが重要である本当の理由は、それがないとコンパイラは encoded を介した書き込みが unencoded を介した読み取りに影響を与えないことを認識できないからです。たとえば、

encoded == unencoded+1

エンコードへの各書き込みは、エンコードされていないからの以降の各読み取りに影響するため、コンパイラは書き込みが完了するまでロードをスケジュールできません。 restrictは、2つのポインターが同じメモリに影響を与えないことをコンパイラーに約束するため、パイプラインのストールを回避するために十分に先にロードをスケジュールできます。

あなたは、それが痛くないことは正しいと思います。ループポインター(pと呼ぶ)は、ループの最後でencodedEndと等しくなります。ただし、ループの後に(pまたはencodedEndから)アクセスする必要はないため、問題にはなりません。 encodedEndから何も書き込まれたり読み込まれたりすることはないので、最適化するものは何もないので、それが助けになるとは思いません。

しかし、最初の2つの制限が本当に役立つはずであることに同意します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top