基本的な原則から始めましょう:あなたのインストラクターがあなたに言ったことはしばしば正確に逆です。通常、書き込みは読み取りよりも高速です。具体的には(少なくとも最新のCPUでは)書き込みとは、アドレスと値をキューに入れることを意味します。CPUの他の部分は、その値のメモリへの書き込みを処理できますが、実行ユニットはさらに多くの命令を実行できます。ただし、書き込みキューがすでにいっぱいになっているときに、さらにデータを書き込もうとすると、命令ストリームが停止する可能性があります。
対照的に、比較を行うには、データがまだキャッシュにない場合、アドレスをメモリに書き出してから、データがメモリから到着するまでストールして、適切な比較に使用できるようにする必要があります。
比較では、フラグレジスタも使用されます。フラグレジスタは、ほとんどの命令で変更されるため、「レジスタ圧力」が大きくなります。これにより、他の方法では利用できる命令レベルの並列性を防ぐことができます。
さて、他の目的ですぐに使用する予定がない限り、一般的に、問題のデータでキャッシュを汚染することは避けたいと思うのは事実です。一部のキャッシュは、書き込みにキャッシュスペースを割り当てないことで、これを完全に回避します。つまり、最近データを読み取って既にキャッシュにある場合を除いて、データに書き込んでもキャッシュに移動しません。データをメインメモリに直接書き込むだけです。
最近の多くの(ほとんど?)プロセッサは、キャッシュポリシーに関係なく、常にメモリに直接書き込む命令も備えています。Intelは(たとえば)これらの非一時的なストア(たとえば、MOVNTQおよびMOVNTPS)を呼び出します。ただし、これらを正しく使用するには少し注意が必要です。通常のメモリ書き込みとは異なり、デフォルトではキャッシュの一貫性は保証されません。他のプロセッサが書き込みの結果を確認できるように、書き込み後にSFENCE命令を実行する必要があります。
比較を行う価値があるもう1つの場合は、1回の比較で大量の書き込みを回避できる場合です。たとえば、配列が非常にまばらで、数百のエントリのうち約1つだけがnull以外であったと仮定します。このような場合、(一例として)ビットマップの1ビットがポインターがnullかどうかを示すビットマップを使用できます。このような場合、単一の64ビット比較により、(たとえば)それぞれ64ビットの64の異なるポインターへの書き込みを回避できます。
ただし、ポインタを個別に確認しても利点はありません。具体的には、比較を行う前に各ポインタをキャッシュにロードする必要があるため、キャッシュを汚染しないように1つずつ比較することをお勧めします。自滅的な提案。