我有double x
和double y
。我需要将其转换为int boxnum
,它被定义为 (floored) 索引,该索引(x,y)
落在WIDTH x HEIGHT
网格中,大小为BOX_SIZE
。超过的坐标WIDTH
被回绕;同上HEIGHT
。
我目前正在使用:
( (((int)(x))/BOX_SIZE)%WIDTH+ WIDTH*((((int)(y))/BOX_SIZE)%HEIGHT) )
该语句目前占用了我执行时间的 20%,如果我让它对负坐标完全安全,情况会变得更糟(大约 40-50%):
( (( ((int)(x)) /BOX_SIZE)%WIDTH+WIDTH)%WIDTH
+WIDTH*(( (((int)(y)) /BOX_SIZE)%HEIGHT+HEIGHT)%HEIGHT) )
我实际上正在考虑将应用程序完全转换为定点,只是为了避免这种情况,这样我就可以掩码掉我想要的部分,而不是进行这种可怕的转换。
有没有更好的方法来进行这种 double->int 转换?确保这样做是否值得,0<x<WIDTH*BOX_SIZE
所以0<y<HEIGHT*BOX_SIZE
我可以放弃两个余数操作?(这样做太难了,不值得作为基准,除非它可能是一个显着的改进)
编辑:在评论中适当的惩罚后,更多细节:
x
y
是一组(多达 10^6 个)粒子的坐标。我正在使用一种算法,该算法要求我在每个时间步长对一个盒子内的所有粒子进行一些简单的求和。因此,我遍历粒子,计算粒子在哪个盒子中,然后将其用作添加到该盒子的数组索引。粒子经常移动得足够远,以至于它们过去的位置并不能表明它们未来的位置。它们也是无序的,这意味着我不能对此做出任何假设。
WIDTH
, HEIGHT
, 并且BOX_SIZE
在技术上是免费的,只要WIDTH
和HEIGHT
是 的偶数倍BOX_SIZE
。实际上,它们都是指定的编译时间,并且是带有BOX_SIZE=1
. 我已经运行了从WIDTH=HEIGHT=4
to的所有内容WIDTH=HEIGHT=512
,虽然我通常是 2 的平方幂(因为为什么不呢?),WIDTH=37;HEIGHT=193
但应该可以正常工作。
这个计算是不可避免的,每个粒子每个时间步执行一次;在当前的实现中,它被执行了两次。我尝试缓存该值以避免重新计算,但最终基准测试的表现更差,所以我又重新计算了两次。
10 particles/box * 100 WIDTH * 100 HEIGHT* 10000 steps = 1 billion particle*timesteps
在阴凉处运行一分钟以上的基本测试。
这些坐标按照它们的“常规数字”(1-1000)的顺序排列,所以我离任何类型的double
.