首页 > 解决方案 > 初始化组共享变量的最佳实践

问题描述

我正在使用一个大的 groupshared 变量来进行计算,但最近我发现(困难的方式)groupshared 内存没有初始化。对于我的用例,我需要对其进行初始化,因为在所有计算之后我会将其直接复制回纹理。

所以我问有什么更好的方法来解决这个问题?主要是性能方面,因为我认为初始化必须作为整个着色器程序的一部分进行。

这就是我目前处理它的方式,但它似乎没有按预期工作,因为一些数据仍然存在于下一次调度中。基本上每个线程都被分配了一些值来初始化,然后等待其他线程。

#define GroupSize 64
#define FoWMap_Size 4096
groupshared uint _FoWMap[FoWMap_Size];

[numthreads(GroupSize, 1, 1)]
void FOWMapGenerator(uint3 id : SV_DispatchThreadID)
{
    uint instPerThread = FoWMap_Size / GroupSize;

    [unroll]
    for (uint k = 0; k < instPerThread; k++)
    {
        uint realID = (id.x * instPerThread) + k;
        if (realID > FoWMap_Size)
            break;
        
        _FoWMap[realID] = 0;
    }

//wait for all units to finish
GroupMemoryBarrierWithGroupSync();

...
...
...
}

这是我事先快速而草率的方法:

void InitArray(uint size)
{
    for (uint i = 0; i < size; i++)
    {
        _FoWMap[i] = 0;
    }
}

[numthreads(GroupSize, 1, 1)]
void FOWMapGenerator(uint3 id : SV_DispatchThreadID)
{
    InitArray(FoWMap_Size);

...
...
...
}

但是我放弃了这个,因为理论上这意味着每个线程都在完全初始化组共享数组,这在性能方面并不理想。编译器可能正在为我优化这个,但我不确定。

总而言之,您如何初始化组共享数组?我迫切需要建议。

标签: unity3dgraphicsinitializationhlslcompute-shader

解决方案


在您的情况下初始化组共享内存时,您应该使用SV_GroupThreadID组内的本地线程 ID,而不是组间的全局线程 ID。SV_DispatchThreadID

否则,您将超出第二组及以上的数组索引。


推荐阅读