有256位整数类型吗?

问题描述 投票:0回答:3

操作系统:Linux (Debian 10)

CC:海湾合作委员会 8.3

中央处理器:i7-5775C

在 GCC 中有一个

unsigned __int128
/
__int128
,但是有没有办法在 GCC 中有一个
uint256_t
/
int256_t

我读过一个

__m256i
,好像是英特尔的。有没有我可以包含的标题来获取它?

是否像假设的

unsigned __int256
一样有用?我的意思是,如果你可以从/向它分配,比较它们,按位运算等。

它的符号等价物是多少(如果有)?


编辑1:

我做到了:

#include <immintrin.h>
typedef __m256i uint256_t;

并编译。如果我可以用它做一些操作,我会在这里更新它。


编辑2:

发现的问题:

uint256_t   m;
int         l = 5;

m = ~((uint256_t)1 << l);

输出:

error: can’t convert a value of type ‘int’ to vector type ‘__vector(4) long long int’ which has different size
  m = ~((uint256_t)1 << l);
c gcc x86-64 bigint extended-precision
3个回答
11
投票

Clang 具有

_ExtInt
扩展整数 支持除法以外的操作,但 SIMD 对此没有用,因为元素之间有进位1。其他主流 x86-64 编译器甚至都没有;您需要一个库或其他东西来定义自定义类型,并使用 clang 将使用的相同的 add-with-carry 指令。 (或者纯 C2 中效率较低的仿真)。

__m256i
是 AVX2 SIMD 4x
uint64_t
(或更窄的元素大小,如 8x
uint32_t
)。 它不是 256 位标量整数类型,您不能将其用于标量运算,
__m256i var = 1
甚至无法编译
。 x86 SIMD 不支持大于 64 位的整数,而像
__m128i
__m256i
这样的 Intel 内在类型纯粹用于 SIMD。

GCC 的

__int128
/
unsigned __int128
通常使用标量
add/adc
和/或标量
mul
/
imul
,因为 AVX2 通常对扩展精度没有帮助。 (仅适用于元素边界无关紧要的按位 AND/OR/XOR 之类的东西。)


脚注 1:对于 BigInteger 类型,实际上有一些使用 SIMD 的范围,但仅限于专门的格式。更重要的是,您必须手动选择何时重新归一化(传播进位),因此您的计算必须围绕它进行设计;它不是直接替代品。请参阅 Mysticial 对 长整数例程能否从 SSE 中受益?

的回答

脚注 2:不幸的是,C 不提供加法/减法的进位,因此用 C 编写甚至不方便。用 C 编写一个全加器。编译器通常会生成垃圾 asm,它不只是在可用的机器上使用本机 add-with-carry 指令。非常大的整数的扩展精度库,如

GMP
,通常用 asm.
 编写
    
我只在 Pollard Rho 算法中计算“f(x) = (x^2+a) mod n”时才需要“uint256_t”。函数“f”之外的所有变量都是内置类型 __uint128_t.


6
投票

sum = a+b

然后我实现了计算“f()”所需的函数:

carry = sum<a

在这个要点中找到实现:

https://gist.github.com/Hermann-SW/a20af17ee6666467fe0b5c573dae701d


我确实针对 gmplib 函数对我的代码进行了基准测试,并实现了对所有 gmplib 的加速(经过大量工作),有关详细信息: https://www.raspberrypi.org/forums/viewtopic.php?f=33&t=311893&p=1873552#p1873552


函数执行 100 万次的纳秒运行时间:


你可以在 BITCOIN 的源代码上看到一点,他们使用 C 语言的库。如果是 Delphi/Pascal,您可以使用 Fundamentals5 (

https://github.com/fundamentalslib/fundamentals5

-1
投票

© www.soinside.com 2019 - 2024. All rights reserved.