对于计算量巨大的粒子系统,该采用什么技术?
我有一个带有 X 个粒子的粒子系统。 每个粒子都会测试与其他粒子的碰撞。这为每帧提供了 X*X = X^2 次碰撞测试。对于 60f/s,这相当于每秒 60*X^2 次碰撞检测。
这些密集计算的最佳技术方法是什么?我应该使用 F#、C、C++ 还是 C#,还是其他?
以下是约束
- 代码是用最新的 XNA 用 C# 编写的
- 可以考虑多线程
- 没有特殊的算法来测试与最近邻居的碰撞或减少问题
最后一个约束可能很奇怪,所以让我解释一下。 不管约束 3 是什么,给定一个具有巨大计算需求的问题,解决该问题的最佳方法是什么。 算法可以减少问题;然而,根据技术的不同,相同的算法可能会有不同的表现。考虑 CLR 与原生 C 的优缺点。
I have a particle system with X particles.
Each particle tests for collision with other particles. This gives X*X = X^2 collision tests per frame. For 60f/s, this corresponds to 60*X^2 collision detection per second.
What is the best technological approach for these intensive calculations? Should I use F#, C, C++ or C#, or something else?
The following are constraints
- The code is written in C# with the latest XNA
- Multi-threaded may be considered
- No special algorithm that tests the collision with the nearest neighbors or that reduces the problem
The last constraint may be strange, so let me explain.
Regardless constraint 3, given a problem with enormous computational requirement what would be the best approach to solve the problem.
An algorithm reduces the problem; still the same algorithm may behave different depending on technology. Consider pros and cons of CLR vs native C.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
简单的答案是“测量它”。但看看这张图(我借用了这个问题 - 值得您阅读)。
C++ 可能比 MS 的 C# 实现快 10%(对于这个特定的计算),并且比 Mono 的 C# 实现更快。但在现实世界中,C++ 并不比 C# 快多少。
如果您正在进行核心数字运算,您将需要使用 SIMD/< a href="http://en.wikipedia.org/wiki/Streaming_SIMD_Extensions" rel="nofollow noreferrer">SSE CPU 单元。这是 C# 通常不支持的功能 - 但 Mono 通过
Mono.Simd
添加了支持。从图中可以看出,使用 SIMD 单元可以显着提升两种语言的性能。(值得注意的是,虽然 C++ 仍然比 C#“更快”,但与选择使用什么硬件相比,语言的选择对性能的影响很小。正如评论中提到的 - 您选择的算法将有到目前为止效果最大。)
最后,正如 Jerry Coffin 在 他的答案,你也可以在GPU上进行处理。我想它会比 SIMD 更快(但正如我所说 - 测量它)。使用 GPU 的另一个好处是可以让 CPU 自由地执行其他任务。缺点是您的最终用户将需要合理的 GPU。
The simple answer is "measure it". But take a look at this graph (that I borrowed from this question - which is worth your reading).
C++ is maybe 10% faster than MS's C# implementation (for this particular calculation) and faster still against Mono's C# implementation. But in real world terms, C++ is not all that much faster than C#.
If you're doing hard-core number crunching, you will want to use the SIMD/SSE unit of your CPU. This is something that C# does not normally support - but Mono is adding support for through
Mono.Simd
. You can see from the graph that using the SIMD unit gives a significant performance boost to both languages.(It's worth noting that while C++ is still "faster" than C#, the choice of language has only a small effect on performance, compared to the choice of what hardware to use. As was mentioned in the comments - your choice of algorithm will have by far the greatest effect.)
And finally, as Jerry Coffin mentioned in his answer, that you could also do the processing on the GPU. I imagine that it would be even faster than SIMD (but as I said - measure it). Using the GPU has the added beneift of leaving the CPU free to do other tasks. The downside is that your end-users will need a reasonable GPU.
您可能应该考虑使用 CUDA、OpenCL 或 DirectX 计算着色器等在 GPU 上执行此操作。
You should probably consider doing this on the GPU using something like CUDA, OpenCL, or a DirectX compute shader.
扫描和修剪是一种广泛的阶段碰撞检测算法,可能非常适合此任务。如果您可以利用时间一致性,即帧与帧之间的位置差异通常很小,则可以减少处理量。关于这个主题的一本好书是“实时碰撞检测”。
Sweep and prune is a broad phase collision detection algorithm that may be well suited to this task. If you can make use of temporal coherency, that being from frame to frame the location differences are generally small a reduction in processing may be obtained. A good book on the subject is "real time collision detection".
为了简单地加快速度,您可以首先按一个轴排序,然后在进行全面检查之前循环检查该轴上的碰撞...对于每个粒子,您只需要在数组中进一步查找,直到找到一个不存在碰撞的粒子。在该轴上发生碰撞,然后您可以移动到下一个轴。
For a simple speed up you could sort by one axis first and loop through checking for a collision in that axis before doing a full check... For each particle you only need to look further in the array until you find one that doesn't collide in that axis then you can move to the next one.