我编写了两个版本的平滑函数,它将内核应用于9坐标的输出。
float PerlinHeightMapGenerator::defaultSmooth(int x, int z, const float kernel[9])
{
const float top = defaultNoise(x - 1, z + 1) * kernel[0] + defaultNoise(x, z + 1) * kernel[1] + defaultNoise(x + 1, z + 1) * kernel[2];
const float middle = defaultNoise(x - 1, z) * kernel[3] + defaultNoise(x, z) * kernel[4] + defaultNoise(x + 1, z) * kernel[5];
const float bottom = defaultNoise(x - 1, z - 1) * kernel[6] + defaultNoise(x, z - 1) * kernel[7] + defaultNoise(x + 1, z - 1) * kernel[8];
const float total = (top + middle + bottom);
return total;
}
float PerlinHeightMapGenerator::defaultSmooth(int x, int z, const XMVECTOR kernel[3])
{
const XMVECTOR top = XMVector3Dot(XMVectorSet(defaultNoise(x - 1, z + 1), defaultNoise(x, z + 1), defaultNoise(x + 1, z+ 1), 0), kernel[0]);
const XMVECTOR middle = XMVector3Dot(XMVectorSet(defaultNoise(x - 1, z), defaultNoise(x, z), defaultNoise(x + 1, z), 0), kernel[1]);
const XMVECTOR bottom = XMVector3Dot(XMVectorSet(defaultNoise(x - 1, z - 1), defaultNoise(x, z - 1), defaultNoise(x + 1, z - 1), 0), kernel[2]);
XMFLOAT4 answer;
XMStoreFloat4(&answer, XMVectorAdd(top, XMVectorAdd(middle, bottom)));
return answer.x;
}
第二个版本使用向量指令,但是对于我正在使用的输入要慢得多(为整个程序的总执行时间增加了近200毫秒)。矢量化版本不应该更快,因为它可以一次调用三个“defaultNoise”,并且还可以同时进行乘法运算吗?
如果相关,“defaultNoise(x,z)”执行此操作:
float PerlinHeightMapGenerator::defaultNoise(int x, int z)
{
int n = x + z * 57;
n = (n<<13) ^ n;
return static_cast<float>( 1.0f - ( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0f);
};
编辑:我已经尝试了一些我不理解的结果的测试。
首先,我尝试更改它,因此向量化函数采用9个浮点数组,然后将它们复制到函数中的向量;什么都不做。
然后我尝试更改代码,看看如果实际上没有使用任何内核向量会发生什么。首先,将所有内核实例替换为XMVectorSet(1,2,3,4),以便代码为:
const XMVECTOR top = XMVector3Dot(XMVectorSet(defaultNoise(x - 1, z + 1), defaultNoise(x, z + 1), defaultNoise(x + 1, z+ 1), 0), XMVectorSet(1, 2, 3, 4));
const XMVECTOR middle = XMVector3Dot(XMVectorSet(defaultNoise(x - 1, z), defaultNoise(x, z), defaultNoise(x + 1, z), 0), XMVectorSet(1, 2, 3, 4));
const XMVECTOR bottom = XMVector3Dot(XMVectorSet(defaultNoise(x - 1, z - 1), defaultNoise(x, z - 1), defaultNoise(x + 1, z - 1), 0), XMVectorSet(1, 2, 3, 4));
这将程序的执行时间从4秒减少到不到2秒(减少50%)。
然后我尝试用内核[0]替换第一个XMVectorSet(1,2,3,4),这将执行时间增加到大约2100毫秒。用内核[1]替换第二个XMVectorSet(1,2,3,4)将时间增加到2700毫秒;替换最后的第三个向量使时间回到4秒。
我还尝试将浮点数复制到函数内部的向量而不是在调用它之前,结果是相同的。
编辑2:看起来XMVectorSet(1,2,3,4)是一种特殊情况。也许它更快,因为它是4个整数;用XMVectorSet(.0357143f,0.0714286f,0.0357143f,0)替换它会使其速度降低到原始速度。
我仍然不明白为什么矢量化版本会慢一些。