我一直在摸不着头脑,我唯一可以得出的结论是rsRand()
没有在通常用于运行脚本的处理器上实现(例如GPU或CPU)或它无法并行运行。
任何人都可以证实吗?如果是这种情况,是否有一个参考资料列出了哪些函数可以安全地用于性能?
有没有其他方法可以在不使用rsRand()
的情况下获取随机数?
这是我的renderscript文件:
#pragma version(1)
#pragma rs java_package_name(com.example.app)
#pragma rs_fp_relaxed
float width;
float height;
float3 p0, p1, p2, p3;
uchar4 __attribute__((kernel)) gradGen(uint32_t x, uint32_t y)
{
float3 result;
float hd = x / width;
float vd = y / height;
float noise = rsRand((float) 1 / 256) - ((float) 1 / 512); // CULPRIT
hd = 3 * hd * hd - 2 * hd * hd * hd;
vd = 3 * vd * vd - 2 * vd * vd * vd;
result.r = (1 - vd) * ((1 - hd) * p0.r + hd * p1.r) + vd * ((1 - hd) * p3.r + hd * p2.r) + noise;
result.g = (1 - vd) * ((1 - hd) * p0.g + hd * p1.g) + vd * ((1 - hd) * p3.g + hd * p2.g) + noise;
result.b = (1 - vd) * ((1 - hd) * p0.b + hd * p1.b) + vd * ((1 - hd) * p3.b + hd * p2.b) + noise;
return rsPackColorTo8888(result);
}
答案 0 :(得分:3)
rsRand()
在大多数实现中调用平台rand()
(这就是它在CPU后端实现的方式,我不知道任何RS GPU驱动程序实际上在其驱动程序中实现了RNG),所以它会发生比简单的轮班和异或者更重要,更慢。
是的,看看rand()
的仿生实现,你是对的,它是序列化的。也许我会让某人在某个时候移植Mersenne twister。
答案 1 :(得分:2)
而不是想知道,我决定做一个愚蠢的事情并写下我自己的rsRand()
。 Xorshift非常简单,这里有额外的代码来实现PRNG:
uint32_t r0 = 0x6635e5ce, r1 = 0x13bf026f, r2 = 0x43225b59, r3 = 0x3b0314d0;
uchar4 __attribute__((kernel)) gradGen(uint32_t x, uint32_t y)
{
...
// Generate a random number between 0-1
uint32_t t = r0 ^ (r0 << 11);
r0 = r1; r1 = r2; r2 = r3;
r3 = r3 ^ (r3 >> 19) ^ t ^ (t >> 8);
float rnd = (float) r3 / 0xffffffff;
...
}
上述速度很快,随机数的质量足以满足我的应用需求。我仍然有兴趣知道rsRand()
减速背后的细节。