我从三个值A,B,C(无符号的32位整数)开始。而且我必须获得两个值D,E(也是32位无符号整数)。哪里
D = high(A*C);
E = low(A*C) + high(B*C);
我希望两个32位uint相乘会产生64位结果。 “高”和“低”只是我对标记64位乘法结果中的前32位和后32位的 promise 。
我尝试获得一些已经可用的功能的优化代码。我在巨大的循环中只有一小段代码,只有几个命令行,但是它几乎消耗了所有的计算时间(用于数小时计算的物理模拟)。这就是为什么我尝试优化这一小部分的原因,而其余的代码可以保持“用户精心安排”。
有一些SSE指令适用于上述计算例程。 gcc编译器可能会优化工作。但是,如果有必要,我不会拒绝直接在SSE指令中编写一些代码的选项。
请耐心等待我对SSE的经验不足。我将尝试仅象征性地为SSE写一个算法。订购掩膜或理解结构可能会出现一些错误。
A*C
的乘法和B*C
的乘法,并返回两个64位值。 A*C
的64位结果,而R,S是B*C
的64位结果。然后我继续将寄存器中的值重新排列为P,Q,0,R 此算法应返回E和D的正确值。
我的问题:
c++中是否有静态代码生成类似于1-5 SSE算法的SSE例程?我提供具有更高性能的解决方案。如果该算法对标准C++命令有问题,是否有办法在SSE中编写算法?
我使用TDM-GCC 4.9.2 64位编译器。
(注:问题在咨询后被修改)
(注2:我在此http://sci.tuomastonteri.fi/programming/sse中的灵感来自于使用SSE获得更好的性能)
最佳答案
如果我理解正确,则需要计算A * B中潜在的溢出次数。如果是,那么您有2个不错的选择-“使用两倍大的变量”(为uint64写128位数学函数-并不难(或等我明天发布))和“使用浮点类型”:
(浮点数(A)*浮点数(B))/浮点数(C)
因为精度损失最小(假设float为4字节,double为8字节,long为16字节长),并且float和uint32都需要4字节内存(对uint64_t使用double,因为它应该为8字节长):
#include <iostream>
#include <conio.h>
#include <stdint.h>
using namespace std;
int main()
{
uint32_t a(-1), b(-1);
uint64_t result1;
float result2;
result1 = uint64_t(a)*uint64_t(b)/4294967296ull; // >>32 would be faster and less memory consuming
result2 = float(a)*float(b)/4294967296.0f;
cout.precision(20);
cout<<result1<<'\n'<<result2;
getch();
return 0;
}
产生:
4294967294
4294967296
但是,如果您想要真正准确正确的答案,我建议您使用两倍大的类型进行计算
现在,我想到了-您可以为uint64使用long double并为uint32使用double,而不是为uint64编写函数,但是我认为不能保证long double将为128bit,因此您必须进行检查。我会选择更通用的选择。
编辑:
You can write function to calculate that without using anything more
than A, B and result variable which would be of the same type as A.
Just add rightmost bit of (where Z equals B*(A>>pass_number&1)) Z<<0,
Z<<1, Z<<2 (...) Z<<X in first pass, Z<<-1, Z<<0, Z<<1 (...) Z<<(X-1)
for second (there should be X passes), while right shifting the result
by 1 (the just computed bit becomes irrelevant to us after it's
computed as it won't participate in calculation anymore, and it would
be erased anyway after dividing by 2^X (doing >>X)
(必须放在“代码”中,因为这是我的新手,无法找到另一种方法来防止格式化脚本吃掉一半)
这只是一个简单的想法。您必须检查它的正确性(对不起,但是我现在真的很累-但是结果在任何计算点都不应溢出,因为如果我正确的话,最大进位值为2倍,并且算法本身似乎很好)。
如果您仍然需要帮助,明天我将为您编写代码。
关于c++ - 得到一个整数的高半部分和低半部分的乘积,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35160244/