Metal-线程本地的命名空间变量? [英] Metal - Namespace variable that is local to a thread?
问题描述
我正在尝试在Metal中创建一个伪随机数生成器(PRNG),类似于thrust
的RNG,每次在线程内调用RNG 时,它都会产生不同的结果给定特定种子的随机数,在这种情况下为thread_position_in_grid
.我已经将其设置得很完美,并且使用我已有的代码,现在我得到了一张漂亮的均匀随机图片.
I'm trying to create a Pseudo Random Number Generator (PRNG) in Metal, akin to thrust
's RNG , where every time you call the RNG within a thread it produces a different random number given a particular seed, which in this case, will be the thread_position_in_grid
. I have it set up perfectly, and I get a nice uniformly random picture right now using the code I have.
但是,我的代码在每个线程中只能运行一次.我想实现一个next_rng()
函数,该函数使用最后的结果作为种子返回一个新的rng
.但是,由于我的RNG是命名空间,因此我无法存储最后的结果,并且我只能将最后的结果存储在constant
地址空间中,该地址空间不可更新.有什么办法可以解决这个问题/重组我的代码来避免这种情况?
However, my code only works once per thread. I want to implement a next_rng()
function that returns a new rng
using the last result as a seed. I am having trouble storing that last result, however, as my RNG is a namespace, and I can only store the last result in constant
address space, which is un-updateable. Is there any way to get around this/restructure my code to avoid this?
我可以在线找到的最佳帮助是这篇SO帖子不幸的是,这对我不起作用,因为我无法像在解决方案中那样将变量声明为函数内的静态变量.
The best help I could find online was this SO post that unfortunately doesn't work with me because I can't declare a variable as static within a function as they do in their solution.
如果有帮助,我愿意以任何方式重组我的代码.我可以将其转换为静态类或类之类的东西吗?毫无头绪,但我只想要一个PRNG
我的代码(简体)基本上与该帖子的结构相同:
My code (simplified) basically has the same structure as that post's:
namespace metal_rng {
thread unsigned* last_seed() {
thread uint last_seed = 1; // Doesn't work because last-seed falls out of scope after the function quits
// The following comment line doesn't even compile:
// thread static uint last_seed = 1;
return &last_seed;
}
unsigned TausStep(const unsigned z, const int s1, const int s2, const int s3, const unsigned M)
{
unsigned b=(((z << s1) ^ z) >> s2);
return (((z & M) << s3) ^ b);
}
device float rng(const int initial_seed) {
int seed = initial_seed * 1099087573UL;
unsigned hashed = (1664525*(*last_seed()) + 1013904223UL);
*last_seed() = hashed
return (hashed) * 2.3283064365387e-10;
}
device float next_rng() {
if (*last_seed() == 0) {
return 0.0;
} else {
unsigned hashed = (1664525*(*last_seed()) + 1013904223UL);
return (hashed) * 2.3283064365387e-10;
}
}
}
框架已完成并在此处整齐地打包:链接
推荐答案
我最终使用了@KenThomases的建议,并且我刚刚为RNG创建了一个类.我打包了代码,并将其称为RNG Loki
. 如果有人将来想使用它,则是此仓库的链接.
I ended up using @KenThomases' suggestions and I just created a class for the RNG. I packaged the code and called the RNG Loki
. Here is the link to the repo if anyone wants to use it in the future.
这篇关于Metal-线程本地的命名空间变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!