更快地转换1D->;使用2维幂的3D

更快地转换1D->;使用2维幂的3D,3d,pseudocode,data-conversion,3d,Pseudocode,Data Conversion,我正在尝试优化对3D环境数据的访问和更改,因为有些操作必须执行数百万次。目前,我有以下优化: 使用平面阵列(1D) 尺寸单位为2的幂 在可能的情况下进行位移位,而不是乘法/除法 三维矢量的索引如下所示: X向量的变化将使指数增加/减少1 Y向量的更改将使索引增加/减少3DEnvironmentSize.X Z向量的更改将使索引增加/减少3DEnvironmentSize.X*3DEnvironmentSize.Y 给定以下伪代码: mapSize.X = 4 mapSize.Y = 4

我正在尝试优化对3D环境数据的访问和更改,因为有些操作必须执行数百万次。目前,我有以下优化:

  • 使用平面阵列(1D)
  • 尺寸单位为2的幂
  • 在可能的情况下进行位移位,而不是乘法/除法
三维矢量的索引如下所示:

  • X向量的变化将使指数增加/减少1
  • Y向量的更改将使索引增加/减少3DEnvironmentSize.X
  • Z向量的更改将使索引增加/减少3DEnvironmentSize.X*3DEnvironmentSize.Y
给定以下伪代码:

mapSize.X = 4
mapSize.Y = 4
mapSize.Z = 2

Xdif = 1
Ydif = mapSize.X = 4
Zdif = mapSize.X * mapSize.Y = 16

Xexponent = log2(Xdif) = log2(1) = 0 (2^0 = 1 = Xdif)
Yexponent = log2(Ydif) = log2(4) = 2 (2^2 = 4 = Ydif)
Zexponent = log2(Zdif) = log2(16) = 4 (2^4 = 16 = Zdif)
可以使用以下公式从3D->1D给定向量(1,2,1)开始:

location.X = 1
location.Y = 2
location.Z = 1

shiftIndex.X = location.X << Xexponent = 1 << 0 = 1
shiftIndex.Y = location.Y << YExponent = 2 << 2 = 8
shiftIndex.Z = location.Z << Zexponent = 1 << 4 = 16

index = shiftIndex.X + shiftIndex.Y + shiftIndex.Z = 1 + 8 + 16 = 25

有没有任何方法可以利用位移位(或其他相关的方法)来加快速度?我已经试着处理这个问题有一段时间了,但如果一开始可能的话,我无法破解它。

你只是想把3个数字打包成一个更大的数字吗

如果是这样的话,你为什么不换个面具呢

ThreeToOne(v3) -> v3.x | (v3.y << 8 ) | (v3.z << 16)

OneToThree(v) -> v3(v & 0xFF, v >> 8 & 0xFF, v >> 16 & 0xFF)
ThreeToOne(v3)->v3.x(v3.y>8&0xFF,v>>16&0xFF)

我在别处得到了答案

当你除以一个2次幂的数字时,你可以用一个2次幂指数的右移运算来代替这个除法。 模运算可以用位and运算符和n-1替换(如果是2的幂次运算,则再次替换)。其中n是您潜水时使用的数字。 因此,总结该准则:

mapSize.X = 4
mapSize.Y = 4
mapSize.Z = 2

Xdif = 1
Ydif = mapSize.X = 4
Zdif = mapSize.X * mapSize.Y = 16

XDifExponent = log2(Xdif) = log2(1) = 0 (2^0 = 1 = Xdif)
YDifExponent = log2(Ydif) = log2(4) = 2 (2^2 = 4 = Ydif)
ZDifExponent = log2(Zdif) = log2(16) = 4 (2^4 = 16 = Zdif)

XSizeExponent = log2(mapSize.X) = log2(4) = 2 (2^2 = 4 = mapSize.X)
YSizeExponent = log2(mapSize.Y) = log2(4) = 2 (2^2 = 4 = mapSize.Y)
ZSizeExponent = log2(mapSize.Z) = log2(2) = 1 (2^1 = 2 = mapSize.Z)

Vector3D -> Index example:
location.X = 1
location.Y = 2
location.Z = 1

shiftIndex.X = location.X << XDifExponent = 1 << 0 = 1
shiftIndex.Y = location.Y << YDifExponent = 2 << 2 = 8
shiftIndex.Z = location.Z << ZDifExponent = 1 << 4 = 16

index = shiftIndex.X + shiftIndex.Y + shiftIndex.Z = 1 + 8 + 16 = 25

Index -> Vector3D example:
index = 30

location.X = index & (mapSize.X - 1) = 2
location.Y = (index >> XSizeExponent) & (mapSize.Y - 1) = 3
location.Z = ((index >> XSizeExponent) >> YSizeExponent) & (mapSize.Z - 1) = 1
mapSize.X=4
mapSize.Y=4
mapSize.Z=2
Xdif=1
Ydif=mapSize.X=4
Zdif=mapSize.X*mapSize.Y=16
XDifExponent=log2(Xdif)=log2(1)=0(2^0=1=Xdif)
YDifExponent=log2(Ydif)=log2(4)=2(2^2=4=Ydif)
Zdif指数=log2(Zdif)=log2(16)=4(2^4=16=Zdif)
XSizeExponent=log2(mapSize.X)=log2(4)=2(2^2=4=mapSize.X)
YSizeExponent=log2(mapSize.Y)=log2(4)=2(2^2=4=mapSize.Y)
ZSizeExponent=log2(mapSize.Z)=log2(2)=1(2^1=2=mapSize.Z)
Vector3D->索引示例:
位置X=1
位置Y=2
位置Z=1
shiftIndex.X=location.X>ysizeindex)和(mapSize.Z-1)=1

感谢您的回答,但不,我正在尝试更快地访问数组中的元素。但是,使用1D数组的缺点是需要根据索引计算坐标。我正在尝试优化完成这项工作的方式(使之尽可能快)。
mapSize.X = 4
mapSize.Y = 4
mapSize.Z = 2

Xdif = 1
Ydif = mapSize.X = 4
Zdif = mapSize.X * mapSize.Y = 16

XDifExponent = log2(Xdif) = log2(1) = 0 (2^0 = 1 = Xdif)
YDifExponent = log2(Ydif) = log2(4) = 2 (2^2 = 4 = Ydif)
ZDifExponent = log2(Zdif) = log2(16) = 4 (2^4 = 16 = Zdif)

XSizeExponent = log2(mapSize.X) = log2(4) = 2 (2^2 = 4 = mapSize.X)
YSizeExponent = log2(mapSize.Y) = log2(4) = 2 (2^2 = 4 = mapSize.Y)
ZSizeExponent = log2(mapSize.Z) = log2(2) = 1 (2^1 = 2 = mapSize.Z)

Vector3D -> Index example:
location.X = 1
location.Y = 2
location.Z = 1

shiftIndex.X = location.X << XDifExponent = 1 << 0 = 1
shiftIndex.Y = location.Y << YDifExponent = 2 << 2 = 8
shiftIndex.Z = location.Z << ZDifExponent = 1 << 4 = 16

index = shiftIndex.X + shiftIndex.Y + shiftIndex.Z = 1 + 8 + 16 = 25

Index -> Vector3D example:
index = 30

location.X = index & (mapSize.X - 1) = 2
location.Y = (index >> XSizeExponent) & (mapSize.Y - 1) = 3
location.Z = ((index >> XSizeExponent) >> YSizeExponent) & (mapSize.Z - 1) = 1