Metal-线程本地的命名空间变量? [英] Metal - Namespace variable that is local to a thread?

查看:98
本文介绍了Metal-线程本地的命名空间变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆