c - Is there a 256-bit integer type?
问题描述
OS: Linux (Debian 10)
CC: GCC 8.3
CPU: i7-5775C
There is a unsigned __int128
/__int128
in GCC, but is there any way to have a uint256_t
/int256_t
in GCC?
I have read of a __m256i
which seems to be from Intel. Is there any header that I can include to get it?
Is it as usable as a hypothetic unsigned __int256
? I mean if you can assign from/to it, compare them, bitwise operations, etc.
What is its signed equivalent (if any)?
EDIT 1:
I achieved this:
#include <immintrin.h>
typedef __m256i uint256_t;
and compiled. If I can do some operations with it, I'll update it here.
EDIT 2:
Issues found:
uint256_t m;
int l = 5;
m = ~((uint256_t)1 << l);
ouput:
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);
解决方案
Clang 具有支持除法以外的操作的_ExtInt
扩展整数,但 SIMD 对此没有用,因为元素之间有进位1。其他主流 x86-64 编译器甚至没有。您需要一个库或其他东西来定义自定义类型并使用 clang 将使用的相同 add-with-carry 指令。(或纯 C 2中效率较低的仿真)。
__m256i
是 AVX2 SIMD 4x uint64_t
(或更窄的元素大小,如 8x uint32_t
)。 它不是 256 位标量整数类型,您不能将其用于标量操作,__m256i var = 1
甚至无法编译. 没有 x86 SIMD支持大于 64 位的整数,并且 Intel 内部类型喜欢__m128i
并且__m256i
纯粹用于 SIMD。
GCC 的__int128
/unsigned __int128
通常使用标量add/adc
和/或标量mul
/ imul
,因为 AVX2 通常对扩展精度没有帮助。(仅适用于元素边界无关的按位 AND/OR/XOR。)
脚注 1:对于 BigInteger 类型实际上有一些使用 SIMD 的范围,但只能使用专门的格式。更重要的是,您必须手动选择何时重新规范化(传播进位),因此您的计算必须围绕它进行设计;它不是直接替代品。请参阅 Mysticial 关于长整数例程可以从 SSE 中受益的答案吗?
脚注2:不幸的是,C不提供加法/减法的进位,因此用C编写甚至不方便。/在 sum = a+b
没有carry = sum<a
进位的情况下进行执行,但是用C编写全加器要困难得多。编译器通常会制作垃圾 asm,而不仅仅是在可用的机器上使用本机 add-with-carry 指令。用于非常大整数的扩展精度库,如GMP,通常用 asm 编写。
推荐阅读
- javascript - WordPress没有显示没有插件的对象GoogleMapsAPI
- excel - 如何更新而不是替换另一个工作簿中的数据?
- c# - API 生成承载令牌以通过 Web GUI 自动登录?
- codeigniter - 如何检查数组购物车上的值
- javascript - 如何在谷歌表格脚本中更快地突出显示重复项?
- java - JMeter 无法使用 JDBC 连接连接到 Phoenix
- go - 为什么在 runtime.GOMAXPROCS(1) 时单个 goroutine 比多个 goroutine 运行得慢?
- jsf - 从 Session Bean 中得不到任何价值
- go - 关于接口分配的困惑
- excel - 下标超出范围:Debug.Print arr(i, 1)