3

行列数値ホットスポットを最適化しています。

現在、パフォーマンスを向上させるためにブロッキングとループ展開を行っています。ただし、わざと縁を剥がすのは避けています。代わりに、ブロッキング ステップをオーバーフローさせます。もちろん、アルゴリズムは初期化されていない値に触れます。

ただし、行列はオーバーフローに対処するために事前に十分に割り当てられているため、実際にメモリ位置に不正にアクセスすることはありません。

私はいくつかの理由でピーリングをしません。

  • 怠惰
  • ピーリング ボーダー ケースの局所性が非常に悪いため、パフォーマンスが低下しました。
  • 複雑なボーダー ピーリング コードを回避するため。

しかし、初期化されていない値に触れるこれらのオーバーフローしたアクセスが実際にパフォーマンスの低下を引き起こすかどうか疑問に思っていますか?

初期化されていないアクセスがどこで発生するかは予想通りわかっており、それらも valgrind を介して報告されています。Intel の VTune を使用してコードのプロファイリングも行いましたが、これによるパフォーマンスの低下を示す兆候は見られませんでした。

4

1 に答える 1

5

つまらないものを邪魔にならないようにするためだけに:

標準によると、初期化されていないデータを使用すると、悪いことが起こる可能性があります。(標準では、例外をトリガーする可能性のある「トラップ」値を許可しています。) しかし、すべての実用的な目的では、これはおそらくここでは当てはまりません。


整数を扱っている場合、初期化されていないデータにアクセスして操作しても、パフォーマンスには影響しません。(除算を除いて、すべての操作は通常固定レイテンシです)

float-pointの場合、次の 2 つの問題があります。

  1. NaN のシグナリング
  2. 非正規化値

環境によっては、NaN を通知すると、ハードウェア例外がトリガーされる場合があります。したがって、これは実際にはパフォーマンスの問題ではなく、正確性の問題になります。

デノーマルフロートがこれと関係があるというのは直観に反するかもしれません。ただし、 初期化されていないデータは非正規化される可能性が高くなります。

そして、非正規化された浮動小数点をいじりたくないでしょう。

したがって、不運にも初期化されていない値に非正規化された値が 1 つでもある場合は、各ループ反復の最後に厄介な 100 サイクル以上のペナルティが予想されます。ループの大きさに応じて、これは問題になる場合と問題にならない場合があります。

はいえ、初期化されていないデータが非正規化されやすいのはなぜですか? 浮動小数点値の最初の数ビットがゼロの場合、非正規化されます。それはとても簡単です。データが整数または 64 ビット ポインターであった場合は、浮動小数点値として再解釈されると非正規化されます。


提案:

  • データをゼロ初期化します。コストが高すぎる場合は、少なくともエンドポイントをゼロで初期化してください。
  • そのクリーンアップ コードを挿入して、初期化されていないデータにアクセスしないようにします。ダフのデバイスのようなものが適切かもしれません。私は通常、一連のバイナリ削減 if ステートメントを好みますが。
于 2012-08-14T00:48:48.500 に答える