- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我的动机:我正在使用一种算法来模拟种群动态,我希望使用 CUDA 以便能够在数值模拟中考虑大量节点。虽然这是我第一次在 GPU 上运行代码,但到目前为止结果看起来很有希望。
背景:我需要考虑随机噪声,它在我打算研究的复杂系统的演化过程中起着至关重要的作用。据我了解,与 CPU 上的类似操作相比,CUDA 中的随机数生成可能相当麻烦。在文档中,我看到必须存储 RNG 的状态,并将其继续提供给需要(生成和)使用随机数的内核(全局函数)。我找到了 these examples非常有启发性,也许您还推荐我阅读有关此内容的其他内容?
问题:生成 n 个种子值,将它们存储在设备全局内存中的数组中,然后将它们提供给内核,内核又生成一对随机数的好处是什么?使用,而不是生成 2n 个随机数,将它们存储在设备全局内存中,然后将它们直接提供给需要使用它们的内核?我一定在这里遗漏了一些真正重要的东西,因为在我看来,在第二种情况下肯定会节省资源(示例中从未使用过)。对于生成的数字的分配,似乎也更安全。
我的代码很长,但我试着用一个简短的例子来说明我需要什么。在这里:
我的代码:
#include <cstdlib>
#include <stdio.h>
#include <cuda.h>
#include <curand.h>
#include <math.h>
__global__ void update (int n, float *A, float *B, float p, float q, float *rand){
int idx = blockIdx.x*blockDim.x + threadIdx.x;
int n_max=n*n;
int i, j;
i=idx/n; //col
j=idx-i*n; //row
float status;
//A, B symmetric
//diagonal untouched, only need 2 random numbers per thread
//i.e. n*(n-1) random numbers in total
int idx_rand = (2*n-1-i)*i/2+j-1-i;
if(idx<n_max && j>i){
if(rand[idx_rand]<p){
status=A[idx];
if(status==1){
if(rand[idx_rand+n*(n-1)/2] < q){
B[idx]=-1.0f;
B[i+n*j]=-1.0f;
}
}
else if(status==0){
if(rand[idx_rand+n*(n-1)/2] < q){
B[idx]=1.0f;
B[i+n*j]=1.0f;
}
}
}
}
}
__global__ void fill(float *A, int n, float num){
int idx = blockIdx.x*blockDim.x + threadIdx.x;
if(idx<n){
A[idx]=num;
}
}
void swap(float** a, float** b) {
float* temp = *a;
*a = *b;
*b = temp;
}
int main(int argc, char* argv[]){
int t, n, t_max, seed;
seed = atoi(argv[1]);
n = atoi(argv[2]);
t_max = atoi(argv[3]);
int blockSize = 256;
int nBlocks = n*n/blockSize + ((n*n)%blockSize == 0?0:1);
curandGenerator_t prng;
curandCreateGenerator(&prng, CURAND_RNG_PSEUDO_DEFAULT);
curandSetPseudoRandomGeneratorSeed(prng, (unsigned long long) seed);
float *h_A = (float *)malloc(n * n * sizeof(float));
float *h_B = (float *)malloc(n * n * sizeof(float));
float *d_A, *d_B, *d_rand;
cudaMalloc(&d_A, n * n * sizeof(float));
cudaMalloc(&d_B, n * n * sizeof(float));
cudaMalloc(&d_rand, n * (n-1) * sizeof(float));
fill <<< nBlocks, blockSize >>> (d_A, n*n, 0.0f);
fill <<< nBlocks, blockSize >>> (d_B, n*n, 0.0f);
for(t=1; t<t_max+1; t++){
//generate random numbers
curandGenerateUniform(prng, d_rand, n*(n-1));
//update B
update <<< nBlocks, blockSize >>> (n, d_A, d_B, 0.5f, 0.5f, d_rand);
//do more stuff
swap(&d_A, &d_B);
}
cudaMemcpy(h_A, d_A, n*n*sizeof(float),cudaMemcpyDeviceToHost);
//print stuff
curandDestroyGenerator(prng);
cudaFree(d_A);
cudaFree(d_B);
cudaFree(d_rand);
free(h_A);
free(h_B);
return 0;
}
我希望你能告诉我它出了什么问题(以及一些关于如何修复它的提示)。如果专家们能告诉我在最好的情况下我可以节省多少(运行时间),在他们能想到的所有性能调整之后,那就太好了,因为我现在手头有几项任务并且成本-因此,“学习时间”方面的好处非常重要。
就是这些了,感谢阅读!
仅作记录,我的硬件规范如下。不过,我计划在某个时候为此使用 Amazon EC2。
我的(当前)硬件:
Device 0: "GeForce 8800 GTX"
CUDA Driver Version / Runtime Version 5.5 / 5.5
CUDA Capability Major/Minor version number: 1.0
Total amount of global memory: 768 MBytes (804978688 bytes)
(16) Multiprocessors, ( 8) CUDA Cores/MP: 128 CUDA Cores
GPU Clock rate: 1350 MHz (1.35 GHz)
Memory Clock rate: 900 Mhz
Memory Bus Width: 384-bit
Maximum Texture Dimension Size (x,y,z) 1D=(8192), 2D=(65536, 32768), 3D=(2048, 2048, 2048)
Maximum Layered 1D Texture Size, (num) layers 1D=(8192), 512 layers
Maximum Layered 2D Texture Size, (num) layers 2D=(8192, 8192), 512 layers
Total amount of constant memory: 65536 bytes
Total amount of shared memory per block: 16384 bytes
Total number of registers available per block: 8192
Warp size: 32
Maximum number of threads per multiprocessor: 768
Maximum number of threads per block: 512
Max dimension size of a thread block (x,y,z): (512, 512, 64)
Max dimension size of a grid size (x,y,z): (65535, 65535, 1)
Maximum memory pitch: 2147483647 bytes
Texture alignment: 256 bytes
Concurrent copy and kernel execution: No with 0 copy engine(s)
Run time limit on kernels: Yes
Integrated GPU sharing Host Memory: No
Support host page-locked memory mapping: No
Alignment requirement for Surfaces: Yes
Device has ECC support: Disabled
Device supports Unified Addressing (UVA): No
Device PCI Bus ID / PCI location ID: 7 / 0
最佳答案
一般来说,随机数生成是一个可以在 GPU 上并行化的过程,因此在许多情况下,可以利用 GPU 比在 CPU 上更快地生成数字。这是使用像 CURAND 这样的 API/库的主要动机。
What is the advantage of generating n seed values, store them in an array on the device global memory, and then feeding them to the kernel which in turn generates a couple of random numbers to use, opposed to generating 2n random numbers, storing them in the device global memory, and then feeding them directly to the kernel which needs to use them?
两者都是有效的方法并且可以利用 GPU 加速:要么预先生成数字并存储它们,要么即时生成它们。
您可能想要考虑一种方法而不是另一种方法的一些原因是:
同样,CURAND 的主要优势在于性能。如果随机数生成只占应用程序总计算成本的一小部分,那么使用哪种方法可能无关紧要,甚至根本不使用 CURAND(例如,代替普通的基于 CPU 的 RNG 方法)。
关于CURAND 和内核,在哪里生成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19691845/
我正在使用 CURAND 库在 CUDA 中编写随机生成代码。我读到的关于随机生成的内容让我相信,如果我使用相同的种子,我将得到相同的随机数集。但是当我测试它时,情况并非如此。请解释我做错了什么。我粘
我正在为一个项目学习 C++,对于我的项目,我需要在 GPU 上生成一个随机数。 为此,我决定使用 cuRAND。 但是,我在这条线上遇到了一个小问题: random > >(time(NULL),
我的动机:我正在使用一种算法来模拟种群动态,我希望使用 CUDA 以便能够在数值模拟中考虑大量节点。虽然这是我第一次在 GPU 上运行代码,但到目前为止结果看起来很有希望。 背景:我需要考虑随机噪声,
我正在尝试使用 CURAND 库生成从 0 到 100 之间完全独立的随机数。因此我将时间作为每个线程的种子并指定“id = threadIdx.x + blockDim.x * blockIdx.x
我正在阅读 CURAND 库 API,我是 CUDA 的新手,我想看看是否有人真的可以向我展示一个使用 CURAND 库生成随机数的简单代码。我正在研究生成大量数字以用于离散事件模拟。我的任务只是开发
我想在 .cu 格式文件中使用 drand48 获得随机统一数,为什么我总是给我 3.90799e-14 这个值 我的代码在 ran_uniform_test.cu 中 #include int m
上下文:我目前正在学习如何正确使用 CUDA,特别是如何使用 CURAND 生成随机数。我学会了here当我需要随机数时,在我的代码中执行核心计算的内核中直接生成随机数可能是明智的。 在 docume
如何为 CURAND_RNG_QUASI_SCRAMBLED_SOBOL64 生成器播种?因为它每次运行时都会给我相同的数字,而且我不能使用 curandSetPseudoRandomGenerato
是否可以在设备仿函数中将 CURAND 与 Thrust 一起使用?最小代码示例可以是: #include struct Move { Move() {} using Positio
我正在使用我们组织内开发的大型 CUDA 矩阵库。我需要保存 CUDA RNG 的状态以获取长时间运行的模拟的快照,并能够在以后恢复它。这很简单,例如,python+numpy: state = nu
我正在考虑将我的计算卡从 nvidia 切换到 amd,因为我需要 double 支持。在这样做之前,我决定在我的 nvidia 卡上学习 opencl,看看我是否喜欢它。我想将以下代码从 CUDA
我正在 NVIDIA CUDA GPU 上研究马尔可夫链蒙特卡罗 (MCMC) 算法实现。 CPU MCMC 算法使用高质量的 Mersenne twiner 随机数生成器,我想在我编写的 GPU 内
对于安全(或错误检查)的 CUDA 调用(例如 cudaMemcpy、cudaMalloc、cudaFree 等函数),我们可以定义一个 wrapper ,像这样的东西: #define cuSafe
我有以下代码,我正在尝试使用 nvcc 进行编译。 代码: #include #include #include #include int main(void) { size_t n
问题我正在尝试使用 OpenACC 和 cuRAND 库生成随机数。我有一段简单的代码(只是尝试了一些事情),它基本上是 pgi cuRAND 示例 (/opt/pgi/linux86-64/2018
我花了很多时间试图找出这个问题的原因。以下代码尝试在 device 上使用 curand 生成一系列正态分布的随机变量。它似乎成功生成了一些,但随后因“遇到非法内存地址错误”而崩溃。非常感谢任何帮助。
我研究了几个小时, MSDN Microsoft - Linker Tools Error LNK2019 How to solve the error LNK2019: unresolved ext
我是一名优秀的程序员,十分优秀!