相关疑难解决方法(0)

从64x64位乘法获得最高64位的合理便携方式?

在C/C++中是否有一种合理的可移植方式可以将128位结果乘以两个64位整数并获得结果的 64位而不是底部的64位?我需要这个来在任意大小的表上分配哈希函数.

c c++

6
推荐指数
1
解决办法
1587
查看次数

装配中纯粹的高位乘法?

要实现0到1之间的实数,通常使用ANSI浮点数或双精度数.但是0到1之间的固定精度数(模数为1的小数)可以有效地实现为32位整数或16位字,它们像正常的整数/字一样添加,但是乘以"错误的方式",这意味着当你乘以X倍时是的,你保留了产品的高位.这相当于乘以0.X和0.Y,其中X的所有位都在小数点后面.同样,-1和1之间的带符号数也可以通过一个额外的位和一个移位来实现.

如何在C中实现固定精度mod 1或mod 2(特别是使用MMX或SSE)?我认为这种表示对于单位矩阵的有效表示非常有用,对于数值密集的物理模拟.它使更多MMX/SSE具有整数量,但您需要更高级别的PMULHW访问权限.

c x86 assembly

5
推荐指数
1
解决办法
1296
查看次数

给出低位字产品,计算两个单词的双字产品(签名)

在Hacker的喜悦中,有一种算法来计算两个(带符号)单词的双字产品.

该函数muldws1使用四次乘法和五次加法来计算两个单词的双字.

在该代码的末尾有一行注释掉

/* w[1] = u*v;                  // Alternative. */
Run Code Online (Sandbox Code Playgroud)

该替代方案使用五次乘法和四次加法,即它为乘法交换加法.

但我认为这种替代方法可以改进.我还没有说过硬件.让我们假设一个假设的CPU,它可以计算两个字但不是高位字的乘积的低位字(例如,对于32位字32x32到低32).在这种情况下,在我看来,这个算法可以改进.这是我假设32位字的想法(相同的概念适用于64位字).

void muldws1_improved(int w[], int32_t x, int32_t y) {
    uint16_t xl = x; int16_t xh = x >> 16;
    uint16_t yl = y; int16_t yh = y >> 16;

    uint32 lo = x*y;
    int32_t t = xl*yh + xh*yl;

    uint16_t tl = t; int16_t th = t >>16;
    uint16_t loh = lo >> 16;

    int32_t cy = loh<tl; //carry
    int32_t hi = xh*yh + th …
Run Code Online (Sandbox Code Playgroud)

c optimization

5
推荐指数
1
解决办法
383
查看次数

如何在汇编中乘以两个十六进制128位数

我在内存中有两个128位的十六进制数字,例如(小端):

x:0x12 0x45 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
y:0x36 0xa1 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
Run Code Online (Sandbox Code Playgroud)

我要执行这两个数字之间的无符号乘法,所以我的新数字将是:

z:0xcc 0xe3 0x7e 0x2b 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
Run Code Online (Sandbox Code Playgroud)

现在,我知道我可以将半个x和y数字移入raxrbx注册,例如,执行mul操作,并对另一半执行相同的操作.问题是,通过这样做,我失去了结转,我不知道如何避免这种情况.大约4个小时我面临这个问题,我能看到的唯一解决方案是二进制转换(and< - > shl,1).

你能给我一些关于这个问题的意见吗?
我认为最好的解决方案是占用一个字节的时间.

algorithm assembly byte x86-64 multiplication

5
推荐指数
2
解决办法
1507
查看次数

将两个64位整数乘以128位然后>>到64位的最快方法?

我需要乘两个符号的64位整数ab在一起,然后转移(128位)的结果到一个符号的64位整数.最快的方法是什么?

我的64位整数实际上代表具有fmt小数位的定点数.fmt被选择为使得a * b >> fmt不应溢出,例如abs(a) < 64<<fmtabs(b) < 2<<fmtfmt==56永远不会溢出64位作为最终结果将是< 128<<fmt,因此适合在一个Int64.

我想这样做的原因是为了快速准确地评估((((c5*x + c4)*x + c3)*x + c2)*x + c1)*x + c0定点格式的形式的五次多项式,每个数字都是带有fmt小数位的带符号的64位定点数.我正在寻找实现这一目标的最有效方法.

c integer fixed-point int128

3
推荐指数
1
解决办法
3126
查看次数

汇编指令中乘法的低位部分和高位部分分别是什么

我正在阅读此链接,简而言之,有人可以向一周前开始学习汇编 x86 和 64 位的人解释当前 C++ 编译器的问题吗?

不幸的是,当前的编译器没有优化 @craigster0 的良好可移植版本,因此如果您想利用 64 位 CPU,则不能使用它,除非作为没有 #ifdef 的目标的后备。(我没有看到优化它的通用方法;您需要 128 位类型或内在函数。)

为了澄清起见,我正在研究汇编的好处,当时我遇到人们在多篇文章中说,当前的编译器在 64 位乘法方面没有进行优化,因为它们使用最低部分,所以它们不执行完整的 64 位乘法什么是不是这个意思。那么,获得较高部分的含义是什么?我在一本书中读到,在 64 位架构中,只有最低 32 位用于 RFlags,这些相关吗?我很困惑吗?

c++ assembly

1
推荐指数
1
解决办法
827
查看次数