简体   繁体   English

我应该使用查找列表而不是大量的乘法吗?

[英]Should i use lookup-lists instead of a lot of multiplication?

in my application I have a very large array of bytes, its a flattened 3 dimensional array, we populate the array using 3 nested for loops (x, y, z) and then we get the values we want by using a little bit of math, most specifically: 在我的应用程序中,我有一个非常大的字节数组,它是一个展平的3维数组,我们使用3个嵌套的for循环(x,y,z)填充该数组,然后通过使用一些数学运算来获得所需的值,最具体地说:

To get an index in the array: 要在数组中获取索引:

return x + z*SizeX + y*SizeX*SizeZ;

and to return the x/y/z coordinates, given an index: 并返回x / y / z坐标(给定一个索引):

int index = pos;
var y = (ushort) (pos/SizeX/SizeZ);
pos -= y*SizeX*SizeZ;
var z = (ushort) (pos/SizeX);
pos -= z*SizeX;
var x = (ushort) pos;

return new BlockPos(x, y, z, index, this);

First off, I would imagine the second one can be made more efficient, i just don't know how to do it, any help there would be appreciated :P 首先,我想第二个可以提高效率,我只是不知道该怎么做,任何帮助将不胜感激:P

My main quesion is, would it be faster for me to make a lookup table for the y and x values (populating when the class is loaded) or is it faster to just leave the multiplication in there? 我的主要问题是,为我创建y和x值的查找表(在加载类时填充)会更快吗?还是只在其中保留乘法会更快?

edit This math is called a LOT in some cases, so if it would be faster, even for a longer startup it would make a differance better. 编辑在某些情况下,该数学运算称为LOT,因此,即使它运行得更快,即使启动时间更长,其差异也会更好。

In most languages and architectures, multiplication will become one (or a few) machine instructions. 大多数语言和体系结构中,乘法将成为一个(或几个)机器指令。 Whilst those instructions may be relatively expensive, they should still be cheaper that performing a lookup operation - and a lookup operation may very well require a multiplication anyway. 尽管这些指令可能相对昂贵,但与执行查找操作相比,它们应该仍然更便宜-无论如何,查找操作很可能需要乘法。

Eg "locate the 4th element of the array" will be 例如,“定位数组的第四个元素”将是

<array base address> + (3 * <array element size>)

The only optimization I'd recommend given your pseudo code is to perform the "constant" operations (eg SizeX*SizeZ ) once, and store those results. 我建议您使用伪代码进行的唯一优化是一次执行“恒定”操作(例如SizeX*SizeZ ),然后存储这些结果。

These might speed you up; 这些可能会加快您的速度;

  • Make SizeX, SizeY, SizeZ constants 使SizeX,SizeY,SizeZ常量
  • Precompute SizeXZ = SizeX * SizeZ and the others (also as constants); 预计算SizeXZ = SizeX * SizeZ及其他(也作为常量);

pre-computing array indices will not gain you much as the precomputed list will be pretty large and looking into it will probably not be faster as doing very little easy math. 预先计算的数组索引将不会给您带来太大的好处,因为预先计算的列表将非常大,并且由于做很少的简单数学运算而对其进行查询可能不会更快。

Array operations in C# are relatively slow (compared to some other languages) because most access is bounds checked. 由于大多数访问都经过边界检查,因此C#中的数组操作相对较慢(与某些其他语言相比)。 There are some ways to get around that; 有一些方法可以解决这个问题。

  • put a tight arrayloop in an unsafe section and use pointers see Large array arithmetics in C# or google for 'matrix multiplication unsafe c#' 在不安全的部分中放置紧密的arrayloop并使用指针,请参见C#或Google中的大型数组算术,以了解“矩阵乘法不安全C#”
  • Mono has a parameter to skip bounds checking. Mono具有跳过边界检查的参数。 It might be faster in your case 您的情况可能会更快

Another speedup can be had to arrange your math loops in such a way that your math processing accesses the large array sequentially. 可能还需要另一种加速方式来安排您的数学循环,以便您的数学处理顺序访问大型数组。 In that way each access benefits from the fact that the data is usually already fetched into the cpu-cache by the previous computation. 这样,每次访问都受益于这样的事实,即数据通常已经由先前的计算提取到了CPU缓存中。 So structure the x,y,z loops in such a way that you get index=1, index=2, index=3 etc. And NOT index = 0, index= 256, index = 512 etc.. 因此,以这样的方式构造x,y,z循环,使您获得index = 1,index = 2,index = 3等。而NOT index = 0,index = 256,index = 512等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM