Random CUDA-多线程

Random CUDA-多线程,random,cuda,numbers,gpu,Random,Cuda,Numbers,Gpu,我正在尝试使用CUDA和GPU使LCG随机数生成器并行运行。但是,实际上我很难同时运行多个线程。下面是代码副本: #include <iostream> #include <math.h> __global__ void rng(long *cont) { int a=9, c=3, F, X=1; long M=524288, Y; printf("\nKernel X is %d\n", X[0]); F=X;

我正在尝试使用CUDA和GPU使LCG随机数生成器并行运行。但是,实际上我很难同时运行多个线程。下面是代码副本:

#include <iostream>
#include <math.h>

__global__ void rng(long *cont)
{

    int a=9, c=3, F, X=1; 
    long M=524288, Y;     
    printf("\nKernel X is %d\n", X[0]);     
    F=X;
    Y=X;
    printf("Kernel F is %d\nKernel Y is %d\n", F, Y);
    Y=(a*Y+c)%M;
    printf("%ld\t", Y);
    while(Y!=F)
    {
        Y=(a*Y+c)%M;
        printf("%ld\t", Y);
    cont[0]++;
    }
}
int main()
{
    long cont[1]={1};
    int X[1];
    long *dev_cont;
    int *dev_X;
    cudaEvent_t beginEvent;
    cudaEvent_t endEvent;
    cudaEventCreate( &beginEvent );
    cudaEventCreate( &endEvent );
    printf("Please give the value of the seed X ");
    scanf("%d", &X[0]);
    printf("Host X is: %d", *X);
    cudaEventRecord( beginEvent, 0);
    cudaMalloc( (void**)&dev_cont, sizeof(long) );
    cudaMalloc( (void**)&dev_X, sizeof(int) );
    cudaMemcpy(dev_cont, cont, 1 * sizeof(long), cudaMemcpyHostToDevice);
    cudaMemcpy(dev_X, X, 1 * sizeof(int), cudaMemcpyHostToDevice);
    rng<<<1,1>>>(dev_cont);
    cudaMemcpy(cont, dev_cont, 1 * sizeof(long), cudaMemcpyDeviceToHost);
    cudaEventRecord( endEvent, 0);
    cudaEventSynchronize (endEvent );
    float timevalue;
    cudaEventElapsedTime (&timevalue, beginEvent, endEvent);
    printf("\n\nYou generated a total of %ld numbers", cont[0]);
    printf("\nCUDA Kernel Time: %.2f ms\n", timevalue);
    cudaFree(dev_cont);
    cudaFree(dev_X);
    cudaEventDestroy( endEvent );
    cudaEventDestroy( beginEvent );
    return 0;
}
@巴迪亚-请建议在这里做什么最好


谢谢

您可以通过
threadIdx
变量来寻址块内的线程。
#include <iostream>
#include <math.h>

__global__ void rng(long *cont, int *L, int *N)
{

    int Y=threadIdx.x;
    Y=N[threadIdx.x];
    int a=9, c=3, i;
    long M=256;
    for(i=0;i<256;i++)
    {
        Y=(a*Y+c)%M;
        N[i]=Y;
        cont[0]++;
    }
}
int main()
{
    long cont[1]={1};
    int i;
    int L[10]={1,25,50,75,100,125,150,175,200,225}, N[256];
    long *dev_cont;
    int *dev_L, *dev_N;
    cudaEvent_t beginEvent;
    cudaEvent_t endEvent;
    cudaEventCreate( &beginEvent );
    cudaEventCreate( &endEvent );
    cudaEventRecord( beginEvent, 0);
    cudaMalloc( (void**)&dev_cont, sizeof(long) );
    cudaMalloc( (void**)&dev_L, sizeof(int) );
    cudaMalloc( (void**)&dev_N, sizeof(int) );
    cudaMemcpy(dev_cont, cont, 1 * sizeof(long), cudaMemcpyHostToDevice);
    cudaMemcpy(dev_L, L, 10 * sizeof(int), cudaMemcpyHostToDevice);
    cudaMemcpy(dev_N, N, 256 * sizeof(int), cudaMemcpyHostToDevice);
    rng<<<1,10>>>(dev_cont, dev_L, dev_N);
    cudaMemcpy(cont, dev_cont, 1 * sizeof(long), cudaMemcpyDeviceToHost);
    cudaMemcpy(N, dev_N, 256 * sizeof(int), cudaMemcpyDeviceToHost);
    cudaEventRecord( endEvent, 0);
    cudaEventSynchronize (endEvent );
    float timevalue;
    cudaEventElapsedTime (&timevalue, beginEvent, endEvent);
    printf("\n\nYou generated a total of %ld numbers", cont[0]);
    printf("\nCUDA Kernel Time: %.2f ms\n", timevalue);
    printf("Your numbers are:");
    for(i=0;i<256;i++)
    {
        printf("%d\t", N[i]);
    }
    cudaFree(dev_cont);
    cudaFree(dev_L);
    cudaFree(dev_N);
    cudaEventDestroy( endEvent );
    cudaEventDestroy( beginEvent );
    return 0;
}
例如,在你的情况下,你可能应该

Y=threadIdx.x
然后使用
Y=(a*Y+c)%M

但总体而言,在CUDA上实现良好的RNG可能非常困难。 所以我不知道你是否想实现自己的生成器只是为了练习


另外,还有一个CURAND库,它提供了大量伪随机和准随机生成器,如XORWOW、MersenneTwister、Sobol等。

它应该在所有线程中执行相同的工作,因为您希望它们执行相同的工作。您应该始终通过寻址线程来区分线程

例如,你应该说thread#1你做这项工作并在这里保存你的工作,thread#2你做那项工作并在那里保存你的工作,然后转到主机并使用该数据

对于每个块中有二维线程的二维块网格,我使用以下代码寻址:

int X = blockIdx.x*blockDim.x+threadIdx.x;
int Y = blockIdx.y*blockDim.y+threadIdx.y;
上面代码中的
X
Y
是线程的全局地址(我认为一维网格和线程就足够了)


还要记住,您不能在内核上使用
printf
函数。GPU不能进行任何中断。为此,您可以使用CUDA SDK示例之一的
cuPrintf
函数,但请阅读其说明以正确使用它。

此答案与问题的编辑部分相关

我没有注意到这是一个递归算法,不幸的是,我不知道如何并行递归算法

生成这256个数字的唯一方法是分别生成它们。i、 e.在第一个线程中生成26个,在第二个线程中生成26个,依此类推。 此代码将执行此操作(这只是内核部分):

#包括
#包括
__全局无效rng(长*续,整数*长,整数*长)
{
int Y=threadIdx.x;
Y=L[threadIdx.x];
int a=9,c=3,i;
长M=256;
int length=ceil((float)M/10);//256除以线程数。

对于(i=(threadIdx.x*length);我同意回答!想法是LCG RNG使用以下公式:Y=(a*Y+c)%M。但是它需要一个原始种子(Y的第一个值)来开始生成数字。该种子的值(Y)应该是1中的一个数字,所以我想做的是有多个具有不同初始种子值的线程。一个线程将有Y=1并产生1000个数字,另一个线程将有Y=1001,等等,但一旦产生1000个数字,线程就需要停止工作,这样它就不会干扰下一个产生数字的线程…我很高兴这是有道理的,但我不知道如何告诉每个线程该做什么。好吧,据我所知,您希望为不同的线程生成不同的随机数子序列。也许使用CURAND库的这段代码可以帮助您:全局无效rng_内核(int*res,int N,int seed){unsigned int tid=blockIdx.x*blockDim.x+threadIdx.x;curand state;//初始化RNG curand_init(seed,tid,0,&state);//为(int i=0;icudaMemcpy
将随机填充数组发送到设备,我们称之为
 Y_dev
(这些是算法中Y的初始数字)。因此,在
\u global\uu
代码中,您应该有这样一个命令
Y=Y_dev[threadIdx.x]
所以每个线程中的
Y
分别初始化,并且您将从每个线程获得异构结果(你的
Y_-dev
的大小应该等于你的线程的大小)。并且不要使用
printf
,将它保存一个数组,然后发送到设备。如果你没有得到它,我会解释更多。我现在明白了……但是我该如何修改我的代码呢?只需添加这两行代码?
int Y=threadIdx.x;
Y=Y\u-dev[threadIdx.x]
但它如何知道要运行哪条指令?我应该在哪里添加这两个命令?首先,您应该添加一个命令,在
main
函数中生成一个随机数组(数组的大小应该等于您要使用的线程的大小)。然后使用
cudaMemcpy
函数将其发送到您的设备,然后在内核中使用它,并在
\u global\uuu
函数中添加这两行。我编辑了我的问题以更新我的当前代码。请告诉我这是否是实现我请求的正确方法。因为我按原样运行了它,但没有得到我所期望的结果预期。存在大量错误。请首先尝试
Y=L[threadIdx.x]
在内核代码的第二行。第二个是将输出保存在
N
数组中的过程。在这个过程中,每个线程将在for循环中运行256次迭代。我将添加另一个答案。是的,这是一个递归算法,与许多随机数生成器一样。然而,此人似乎已经开发了一个算法ithm将与CUDA[link]并行执行此LCG方法我更正了定义
length
length
是每个线程的领域时的错误。您发送的链接方法正是我所写的。感谢您的修复。但是,生成的数字没有任何意义。我将再次编辑我的原始问题,以发布我正在使用的代码和out但我
[wigberto@client2 CUDA]$ ./RNG8


You generated a total of 1 numbers
CUDA Kernel Time: 0.00 ms
Your numbers are:614350480      32767   1132936976      11079   2       0       10      0       1293351837      0       -161443660      48      0       0       614350336       32767    1293351836      0       -161444681      48      614350760       32767   1132936976      11079   2       0       10      0       1057178751      0       -161443660      48       155289096       49      614350416       32767   1057178750      0       614350816       32767   614350840       32767   155210544       49      0       0       1132937352       11079   1130370784      11079   1130382061      11079   155289096       49      1130376992      11079   0       1       1610    1       1       1       1130370408      11079    614350896       32767   614350816       32767   1057178751      0       614350840       32767   0       0       -161443150      48      0       0       1132937352      11079    1       11079   0       0       1       0       614351008       32767   614351032       32767   0       0       0       0       0       0       1130369536      1       1132937352       11079   1130370400      11079   614350944       32767   1130369536      11079   1130382061      11079   1130370784      11079   1130365792      11079   6143510880       614351008       32767   -920274837      0       614351032       32767   0       0       -161443150      48      0       0       0       0       1       0       128     0-153802168      48      614350896       32767   1132839104      11079   97      0       88      0       1       0       155249184       49      1130370784      11079   0       0-1      0       1130364928      11079   2464624 0       4198536 0       4198536 0       4197546 0       372297808       0       1130373120      11079   -161427611      48      111079   0       0       1       0       -153802272      48      155249184       49      372297840       0       -1      0       -161404446      48      0       0       0       0372298000       0       372297896       0       372297984       0       0       0       0       0       1130369536      11079   84      0       1130471067      11079   6303744 0614351656       32767   0       0       -1      0       4198536 0       4198536 0       4197546 0       1130397880      11079   0       0       0       0       0       0       00       0       0       -161404446      48      0       0       4198536 0       4198536 0       6303744 0       614351280       32767   6303744 0       614351656       32767   614351640        32767   1       0       4197371 0       0       0       0       0       [wigberto@client2 CUDA]$
int X = blockIdx.x*blockDim.x+threadIdx.x;
int Y = blockIdx.y*blockDim.y+threadIdx.y;
#include <iostream>
#include <math.h>

__global__ void rng(long *cont, int *L, int *N)
{

    int Y=threadIdx.x;
    Y=L[threadIdx.x];
    int a=9, c=3, i;
    long M=256;
    int length=ceil((float)M/10); //256 divided by the number of threads.
    for(i=(threadIdx.x*length);i<length;i++)
    {
        Y=(a*Y+c)%M;
        N[i]=Y;
        cont[0]++;
    }
}