と がdouble x
ありdouble y
ます。これを に変換する必要があります。これは、サイズ の正方形でグリッドに収まるint boxnum
(フロア化された) インデックスとして定義されます。を超える座標は折り返されます。同上。(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
残りの2つの操作を削除できるようにすることは価値がありますか? (これを行うことは、大幅な改善が見込めない限り、ベンチマークの価値がないほど困難です)
編集:コメントで適切な懲らしめの後、詳細:
x
およびy
は、一連の (10^6 もの) 粒子の座標です。ボックス内のすべての粒子の単純な合計を時間ステップごとに計算するアルゴリズムを使用しています。したがって、粒子全体をループし、粒子が入っているボックスを計算し、それをそのボックスに追加するための配列インデックスとして使用します。パーティクルは、過去の位置が将来の位置を示すものではないほど遠くまで移動することがよくあります。も順不同です。つまり、これについては何も仮定できません。
WIDTH
、HEIGHT
、およびは、およびがの倍数であるBOX_SIZE
限り、技術的には無料です。実際には、それらはすべて指定されたコンパイル時間であり、. 私は からまですべてを実行しましたが、通常は 2 の平方乗ですが (なぜか?)、問題なく動作するはずです。WIDTH
HEIGHT
BOX_SIZE
BOX_SIZE=1
WIDTH=HEIGHT=4
WIDTH=HEIGHT=512
WIDTH=37;HEIGHT=193
この計算は、タイムステップごとにパーティクルごとに 1 回実行されることは避けられません。現在の実装では、2 回実行されます。再計算を避けるために値をキャッシュしようとしましたが、最後のベンチマークのパフォーマンスが低下したため、2 回計算し直しました。
10 particles/box * 100 WIDTH * 100 HEIGHT* 10000 steps = 1 billion particle*timesteps
日陰で1分かけて走る基本的な試運転。
これらの座標は「通常の数値」 (1 ~ 1000) の順序になっているため、double
.