“模拟”一个 64 位整数与两个 32 位整数
我正在为移动设备编写一个计算量非常大的程序,并且仅限于 32 位 CPU。本质上,我正在执行大量数据(> 12k 带符号的 16 位整数)的点积。浮点运算太慢了,所以我一直在寻找一种使用整数类型执行相同计算的方法。我偶然发现了一种叫做 块浮点 算术的东西(链接论文第 17 页)。它做得非常好,但现在我面临着 32 位不足以以足够的精度存储计算输出的问题。
澄清一下,精度不够的原因是我必须大幅降低每个数组元素的精度才能最终得到适合 32 位整数的数字。正是对 16000 件事的总和才让我的结果如此巨大。
有没有一种方法(我希望参考一篇文章或教程)使用两个 32 位整数作为最高有效字和最低有效字和定义它们的算术(+,-, *, /) 有效地处理数据?另外,是否有更好的方法来做这些事情?这种做法有问题吗?我对使用的编程语言相当灵活。我更喜欢 C/C++,但 java 也可以。我确信以前有人这样做过。
I'm writing a very computationally intense procedure for a mobile device and I'm limited to 32-bit CPUs. In essence, I'm performing dot products of huge sets of data (>12k signed 16-bit integers). Floating point operations are just too slow, so I've been looking for a way to perform the same computation with integer types. I stumbled upon something called Block Floating Point arithmetic (page 17 in the linked paper). It does a pretty good job, but now I'm faced with a problem of 32 bits just not being enough to store the output of my calculation with enough precision.
Just to clarify, the reason it's not enough precision is that I would have to drastically reduce precision of each of my arrays' elements to get a number fitting into a 32-bit integer in the end. It's the summation of ~16000 things that makes my result so huge.
Is there a way (I'd love a reference to an article or a tutorial) to use two 32-bit integers as most significant word and least significant word and define arithmetic on them (+, -, *, /) to process data efficiently? Also, are there perhaps better ways of doing such things? Is there a problem with this approach? I'm fairly flexible on programming language I use. I would prefer C/C++ but java works as well. I'm sure someone has done this before.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我非常确定 JVM 必须支持 64 位算术
long
类型,如果平台不支持它,那么 VM 必须模拟它。但是,如果您无法使用float
来解决性能问题,那么 JVM 可能会毁掉您。大多数 C 和 C++ 实现将提供针对 32 位目标模拟的 64 位算术 - 我知道 MSVC 和 GCC 是这样做的。但是,您应该意识到,您可以使用许多整数指令来保存单个浮点指令。您应该考虑该程序的规格不合理,或者您可能可以从其他地方释放性能。
I'm pretty sure that the JVM must support a 64-bit arithmetic
long
type, and if the platform doesn't support it, then the VM must emulate it. However, if you can't afford to usefloat
for performance problems, then a JVM will probably destroy you.Most C and C++ implementations will provide 64-bit arithmetic emulated for 32bit targets- I know that MSVC and GCC do. However, you should be aware that you can be talking about many integer instructions to save a single floating-point instruction. You should consider that the specifications for this program are unreasonable, or perhaps that you could free performance from somewhere else.
是的,只需使用 64 位整数:
Yes, just use 64 bit integers:
维基百科页面上有一个关于任意精度算术的库列表。也许那里的东西对你有用?
There is a list of libraries on the wikipedia page about Arbitrary Precision Arithmetic. Perhaps something on there would work for you?
如果您可以使用 Java,简短的答案是:使用 Java long。 Java 标准将 long 定义为 64 位。任何 JVM 都应该实现这一点,否则不符合标准。没有什么需要CPU支持64位算术。如果它本身不支持,那么 JVM 应该用软件来实现它。
如果您确实有一些不支持 long 的残缺 Java,请使用 BigInteger。这可以处理任意大大小的整数。
If you can use Java, the short answer is: Use Java long's. The Java standard defines a long as 64 bits. Any JVM should implement this or it is not compliant with the standard. Nothing requires the CPU to support 64-bit arithmetic. If it's not natively supported, a JVM should implement it with software.
If you really have some crippled Java that does not support long's, use BigInteger. This handles integers of any arbitrarily-large size.
谈论C/C++。
任何普通编译器都会支持“long long”类型作为 64 位整数,并具有所有普通算术。
与 -O3 结合使用,它有很好的机会在您的平台上输出 64 位算术的最佳代码。
Talking about C/C++.
Any normal compiler would support "long long" type as 64-bit integrs with all normal arithmetic.
Combined with -O3, it gets very good chances of outputting best possible code for 64-bit arithemtic on your platform.