请参阅下面的粗体问题。
我有一个功能C ++程序,我想用CUDA重写。我已经从各种NVIDIA教程和Udacity课程中获得了对如何使用CUDA的合理理解。但我的问题是:在这些教程中的所有示例中,它们总是使用具有非常简单结构的程序作为示例。通常,它只是一个.cu
文件,其中包含各种内核定义,后跟一个main()
函数,它执行一些操作,分配一些设备内存,并运行内核。虽然这些简单的示例有助于我了解如何使用CUDA,但它们并不能帮助我理解如何将CUDA代码集成到包含类的更复杂的程序中。这是关于如何构建CUDA程序的问题。
让我们具体化:
我有一个串行粒子过滤器程序,包含以下源文件:
main.cpp
运行主程序particle_filter.h
和particle_filter.cpp
包含一个包含粒子过滤器所有逻辑的类粒子过滤器类中发生的大量计算是并行化的完美用例。在粒子过滤器类的许多方法中,我想用内核调用替换循环。
我的问题是:
这些内核的定义应该在哪里?
感谢您的帮助
根据下面的评论,这里是particle_filter.cpp
中定义的一种方法的代码。该方法初始化粒子过滤器对象。我想用内核调用替换方法内的for
循环。我在哪里定义内核?内核定义是否成为该类的另一种方法?或者我应该在别处定义内核?内核是应该在同一个源文件中还是在单独的源文件中定义?我知道这最终取决于我,但这里的最佳做法是什么?
void ParticleFilter::init(double x, double y, double theta, double std[]) {
// Set the number of particles
num_particles = 100;
// Declare the random generator
default_random_engine gen;
// Extract the standard deviations for x, y, and theta
double std_x = std[0];
double std_y = std[1];
double std_theta = std[2];
// Creates normal distributions for x, y and theta.
normal_distribution<double> dist_x(x, std_x);
normal_distribution<double> dist_y(y, std_y);
normal_distribution<double> dist_theta(theta, std_theta);
// Create the vector to contain the `num_particles` particles
particles = vector<Particle>(num_particles);
// Create the vector to contain the weight for each particle
weights = vector<double>(num_particles);
// Loop over the particle vector and initialize each particle with the initial (x,y,theta) position
// passed in the arguments with added Gaussian noise and weight 1
for (int i = 0; i < num_particles; i++) {
particles[i].id = i; // Set this particle's ID
particles[i].x = dist_x(gen); // Generate a random value from `dist_x` to set as this particle's x position
particles[i].y = dist_y(gen); // Generate a random value from `dist_y` to set as this particle's y position
particles[i].theta = dist_theta(gen); // Generate a random value from `dist_theta` to set as this particle's orientation theta
particles[i].weight = 1.0; // Set the initial weight for all particles to 1
}
is_initialized = true;
}
答案 0 :(得分:3)
您描述的程序仍然非常简单(这就是为什么我能够冒险回答......也忽略了您的代码)。
我认为您需要做的是以下内容:
确定数据是否完全适合GPU全局内存。
2.1如果确实如此,初始化也可能与GPU相关。
2.2如果没有,那么在GPU上初始化东西的可能性就越小,但是如果你在CPU上做它,它仍然需要有效且多线程,否则GPU可能只是相关的简单的缘故。
.cu
文件(对于内核调用的设备端函数可能.cuh
),或者可能是密切相关的内核组。 (还要记住,不同类型的相同功能=单个模板中的单个模板化内核。)我希望没有具体的例子我能够理解。
上述建议中最棘手的一点是绝对没有。 4.这是我在自己的代码中使用的“桥接”正常编译和NVCC编译的代码:
请注意,第一个文件是我的轻量级Modern-C ++ - ish CUDA Runtime API wrapper library的一部分,这使得主机端编码在几个方面更加方便。 子>