我正在尝试使用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
进行编译。
有人可以解释一下我做错了什么或者至少暗示我提供一些文件/解释吗?任何可以让我开始解决和理解这一点的东西都会受到超级赞赏!
答案 0 :(得分:0)
DirectCompute着色器仍然需要超时检测&amp;驱动程序中的恢复(TDR)行为。这基本上意味着如果着色器需要超过2秒,驱动程序会假设GPU已挂起并重置它。对于DirectCompute来说,这可能很有挑战性,你有意让着色器运行很长时间(比渲染通常要长得多)。在这种情况下,它可能是一个错误,但它需要注意。
使用Windows 8.0或更高版本,您可以在创建设备时使用D3D11_CREATE_DEVICE_DISABLE_GPU_TIMEOUT
来允许长时间运行的着色器。但是,这将适用于所有着色器,而不仅仅是DirectCompute,所以你应该小心使用它。
对于专用系统,您还可以使用registry keys禁用TDR。