0

HLSL を使用して計算シェーダーにバイナリ検索を実装しようとしています。検索キーと配列の値がfloat. 検索キーに一致する配列値がない場合、検索は最後のインデックスを返すことになっています (minIdxそしてmaxIdx、この時点で一致します)。これは、最大数の操作が必要なため、従来のバイナリ検索の最悪のケースです。私はこれを認識しています。

だからここに私の問題があります:

私の実装は次のようになります。

uint BinarySearch (Texture2D<float> InputTexture, float key, uint minIdx, uint maxIdx)
{
    uint midIdx = 0;
    while (minIdx <= maxIdx)
    {
        midIdx = minIdx + ((maxIdx + 1 - minIdx) / 2);
        if (InputTexture[uint2(midIdx, 0)] == key)
        {
            // this might be a very rare case
            return midIdx;
        }

        // determine which subarray to search next
        else if (InputTexture[uint2(midIdx, 0)] < key)
        {
            // as we have a decreasingly sorted array, we need to change the
            // max index here instead of the min
            maxIdx = midIdx - 1;
        }

        else if (InputTexture[uint2(midIdx, 0)] > key)
        {
            minIdx = midIdx;
        }
    }

    return minIdx;
}

これにより、プログラムの実行時にビデオ ドライバーがクラッシュします。コンパイルエラーになりません。

ただし、のif代わりにを使用するwhileと、それを実行でき、最初の反復は期待どおりに機能します。

私はすでにいくつかの検索を行いましたが、これは計算シェーダーでの動的ループで何かをしなければならないのではないかと思います。しかし、コンピューティング シェーダーの経験がなく、HLSL の経験もほとんどないため、途方に暮れているように感じます。

これを でコンパイルしていcs_5_0ます。

誰かが私が間違っていることを説明したり、少なくともいくつかのドキュメント/説明を教えてくれませんか? これを解決して理解するために私を始めることができるものは何でも非常に高く評価されます!

4

1 に答える 1

1

DirectCompute シェーダーは、ドライバーの Timeout Detection & Recovery (TDR) 動作の影響を受けます。これは基本的に、シェーダーに 2 秒以上かかる場合、ドライバーは GPU がハングしたと見なしてリセットすることを意味します。これは、意図的にシェーダーを長時間 (通常のレンダリングよりもはるかに長く) 実行したい DirectCompute では難しい場合があります。この場合はバグかもしれませんが、注意が必要です。

Windows 8.0 以降ではD3D11_CREATE_DEVICE_DISABLE_GPU_TIMEOUT、デバイスの作成時に を使用して長時間実行シェーダーを許可できます。ただし、これは DirectCompute だけでなくすべてのシェーダーに適用されるため、これを一般的に使用する場合は注意が必要です。

特殊用途のシステムでは、レジストリ キーを使用して TDR を無効にすることもできます。

于 2015-09-17T17:41:11.517 に答える