我正在开发一个(c ++,opengl)项目,我需要有很多影响彼此的粒子,如果我是正确的,这被称为nbody问题。有人知道这样的算法有什么解决方案。
我知道barnes hut算法,也许我可以偷看openCL,虽然我不仅仅想知道你是否可以使用其他解决方案。
我将创建的代码有很多:
for(int i = 0; i < num_particles; ++i) {
for(int j = i+1, j < num_particles; ++j)
dist = distance(particles[i],particles[j]);
if(dist > limit) {....}
}
}
亲切的问候, 波吕克斯
答案 0 :(得分:3)
这就是像Octrees这样的数据结构派上用场的地方。他们可以将O(N^2)
循环缩减为O(N*log(N))
,但会牺牲一点精度。
答案 1 :(得分:3)
Kd-trees非常适合在最大距离处查找所有对象(本例中为粒子)。如果树是平衡的,则查找O(log n)
。
答案 2 :(得分:2)
如果你想在很多非常简单的机构上拥有巨大的计算能力 - 对nvidia CUDA感兴趣并在GPU着色器单元上工作。与具有多线程的四核CPU相比,这可以提供更多性能
答案 3 :(得分:0)
你去了:GPU Gems 3。它在CUDA中,但很容易移植到openCL。
但是,这个版本会计算你可能不想要的N²/ 2交互。
答案 4 :(得分:0)
通过4x4像素盒划分1024x512像素区域,为每个盒子中的粒子分配15个单元,具有12k粒子,仅有排除力来计算,对于Intel HD-400(具有12个计算单元,通过,不超过8ms) opencl api)for:
for(each particle) // this part unfolded on N workitems of opencl
for(each neighboring box) {
for(each particle in selected box)
{
dist = distance(particles[i],particles[j]);
if(dist < limit) {/* sqrt, mult, div, add, sub */}
}
}
所以空间分区和使用opencl肯定会提高速度。如果没有分区,暴力需要44ms,这对于具有单通道慢速内存的低端集成gpu来说并不坏。
同时使用第二个cpu,有助于大约0.5ms - 0.1ms,但由于内存在后台存在瓶颈。