Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 基于网格的粒子系统优化_Java_Algorithm_Optimization_Data Structures_Cellular Automata - Fatal编程技术网

Java 基于网格的粒子系统优化

Java 基于网格的粒子系统优化,java,algorithm,optimization,data-structures,cellular-automata,Java,Algorithm,Optimization,Data Structures,Cellular Automata,我已经在Java中实现了一个类似于的游戏,目前发现我的粒子数上限达到了~80k。我的游戏板是一个2D数组,引用“粒子”对象,每一帧都必须更新。不同种类的“粒子”具有不同的行为,可能会根据环境条件(如风或相邻粒子)移动或改变其状态 一些可能生效的“规则”: 如果熔岩类型的粒子与水类型的粒子相邻,两者都会消失,熔岩被黑曜石取代 如果一个气体粒子与熔岩、火、余烬等粒子相邻,它将点燃,并产生火和烟 如果有足够数量的尘埃颗粒堆积在彼此的顶部,那么处于较低水平的尘埃颗粒,就像在压力下一样,可能会成为沉积岩

我已经在Java中实现了一个类似于的游戏,目前发现我的粒子数上限达到了~80k。我的游戏板是一个2D数组,引用“粒子”对象,每一帧都必须更新。不同种类的“粒子”具有不同的行为,可能会根据环境条件(如风或相邻粒子)移动或改变其状态

一些可能生效的“规则”:

  • 如果熔岩类型的粒子与水类型的粒子相邻,两者都会消失,熔岩被黑曜石取代
  • 如果一个气体粒子与熔岩、火、余烬等粒子相邻,它将点燃,并产生火和烟
  • 如果有足够数量的尘埃颗粒堆积在彼此的顶部,那么处于较低水平的尘埃颗粒,就像在压力下一样,可能会成为沉积岩

我四处搜索,没有找到任何算法或数据结构,似乎特别适合加速任务。看来某种形式的回忆录可能有用?四叉树在这里有用吗?我在康威的《生命游戏》中看到过类似的算法。或者,是我不能做太多的事情来提高速度吗?

我不清楚你的问题,但我认为cuda或OpenGL(GPU编程)可以很容易地处理你的ref链接:

Hashlife原则上可以工作,但有两个原因让你不能像Conway Life那样从中得到那么多

首先,它依赖于循环模式。你拥有的单元状态越多,平面结构越不合理,你遇到的缓存命中就越少,你使用暴力的次数就越多

第二,正如另一张海报所指出的,涉及非局部效果的规则要么意味着你的原语(在康威生活4x4中)需要更大,因此你将放弃8x8或16x16或任何大小的分治,以保证你能在n/2时间内正确计算中间部分。 国家的多样性使情况变得更糟。在康威生活中,预先计算所有4x4网格是很常见的,或者至少在缓存中有几乎所有相关的网格。 两个州只有65536个4x4网格(在现代平台上是微不足道的),但只有3个州有43046721个网格。 如果您必须使用8x8原语,它会很快变大,超出任何实际存储空间

因此,基本体越大,状态越多,很快就会变得不现实

解决原始尺寸的一种方法是让岩石规则传播压力。因此,岩石+n(n代表压力)在下一代中变成岩石+(n+1),如果它上面有岩石+m,其中m>=n。达到某个临界值k时,它会变成沉积岩

这意味着细胞仍然只依赖于它们的近邻,但状态的数量会再次增加

如果你有像例子中的“鸟”一样的细胞类型,并且你的速度没有保持在最小值(比如说在任何一个方向上都是-1,0,1),你将完全崩溃。即使如此,这些规则的混乱性质可能会使这些区域的缓存命中率变得越来越小


如果你的规则没有像康威生活经常做的那样导致稳定状态(或重复周期),记忆的回报将是有限的,除非你的飞机大部分是空的

我会使用一个固定的NxN网格来实现这一点,主要是因为每个帧周围移动的点太多,无法从四叉树的递归细分特性中获益。在这种情况下,具有适当调整的数据表示和内存布局的简单数据结构可以带来世界上所有的不同

这里我要为Java做的主要事情实际上是避免将每个粒子建模为对象。它应该是原始数据,就像一些普通的旧数据,比如float或int。您希望能够使用连续处理为空间局部性提供连续性保证,而不必支付填充成本和每个类实例8字节的开销。将冷场与热场分开

例如,你不一定需要知道粒子的颜色来移动它并应用物理。因此,这里不需要AoS表示,它必须在连续的物理过程中将粒子的颜色加载到缓存线中,以便将其逐出而不使用。通过将缓存线与特定过程的无关内存分离,尽可能多地将一起使用的相关内存塞进缓存线

网格中的每个单元格应该只将索引存储到一个粒子中,每个粒子存储到单元格中下一个粒子的索引(一个单独链接的列表,但它是一个侵入式列表,不需要分配节点,只需要将索引使用到数组中)。
-1
可用于指示列表的结尾以及空单元格

要查找感兴趣的粒子之间的碰撞,请查看与正在测试的粒子相同的单元,您可以并行执行此操作,其中每个线程处理一个或多个单元的粒子

NxN网格应该非常精细,因为每帧可以有大量移动粒子。根据您创建的单元格数量,找出适合您输入大小的最佳单元格。您甚至可能有多个网格。如果某些粒子彼此不相互作用,不要将它们放在同一网格中。这里不要担心网格的内存使用情况。如果每个网格单元仅存储单元中第一个粒子的32位索引,则200x200网格仅需要160 KB,每个粒子的32位
next
索引开销

几年前,我在C中使用上述技术(但没有演示游戏中那么多有趣的粒子交互)制作了类似的东西,在速度低于30 FPS之前,在只有2个内核的旧硬件上可以处理大约10 mil的粒子。这对你有好处
cell_x = (int)(particle_x[particle_index] / cell_size)
cell_y = (int)(particle_y[particle_index] / cell_size)
cell_index = cell_y * num_cols + cell_x