文章摘要
文章介绍了一种在C++中实现高效128位无符号整数(u128)的方法,通过组合两个64位整数并利用x64指令集的进位、借位和乘法内联函数来实现基本运算。该方法生成的代码性能与内置的_uint128t相当,专注于固定宽度算术和优化代码生成,适用于几何和数值计算等需要精确范围的场景。
文章总结
构建高效的C++ uint128实现 | Solidean
核心内容:
本文详细介绍了如何用C++实现一个高效的128位无符号整数类型(u128),其性能与编译器内置的__uint128_t相当。实现基于两个64位字段(limbs),通过x64指令集直接映射的进位、借位和乘法内联函数完成算术运算。
关键实现细节:
数据结构表示
cpp struct u128 { u64 low = 0; // 低64位 u64 high = 0; // 高64位 };核心运算实现
- 加法:使用
_addcarry_u64内联函数模拟x64的adc指令 - 减法:使用
_subborrow_u64内联函数对应x64的sbb指令 - 乘法:通过
_mulx_u64实现64x64→128位乘法,组合四个部分积 - 比较:利用借位标志实现无分支比较优化
- 性能优势
- 生成的汇编代码与手写汇编相当
- 加法/减法每条运算仅需2条核心指令
- 乘法通过硬件指令直接支持,避免软件模拟开销
- 设计哲学
- 专注固定位宽运算而非任意精度
- 优先考虑代码生成质量而非抽象层次
- 适用于几何计算等需要确定精度的场景
平台适配说明
- x64平台:使用Intel内联函数集
- MSVC:使用_umul128替代乘法指令
- AArch64:可通过类似指令模式适配
- PowerPC:需使用特定指令(如adde/subfe)
扩展性 该模式可自然扩展到更大整数类型(如u256),文中提到的生产环境已使用到564位整数。
局限说明 - 未实现除法(硬件支持有限) - 当前为无符号版本 - 主要针对Clang/GCC优化
完整代码和编译器输出参见:Godbolt链接
(注:原文中部分数学公式和平台细节说明已简化为技术要点,保留了所有核心实现方法和性能分析内容)
评论总结
这篇评论主要围绕128位整数实现及其应用展开讨论,观点多样且具有技术深度。以下是主要观点总结:
历史应用与实现方法
- 有评论提到过去使用类似UUID的确定性方法处理TenantId和UserId(评论1:"we did UUIDs that made up a TenantId and a UserId, using this exact same logic")
- 另一评论回忆早期平台限制(评论2:"the bad old days where the platform gave you 8-bit ints")
技术实现讨论
- 除法优化:提出使用x64指令的128位除法技巧(评论5:"pre-multiply both dividend and divisor by a large enough power of 2")
- 算法选择:建议使用Karatsuba算法提升乘法性能(评论6:"Karatsuba's Algorithm which uses 3 multiplications instead of 4")
- 类型安全:推荐使用std::uint64t保证位数(评论6:"I would use std::uint64t which guarantees a type of that size")
现有工具与标准
- 指出GCC已支持128位整数(评论8:"GCC alread has this for x64")
- 提到RISC-V缺乏进位位的问题(评论8:"RISC-V has no carry bit and this whole thing becomes awkward")
应用场景探讨
- 质疑128位整数的实际需求(评论7:"What is an application for an int128 type anyways?")
- 个人经历:分享学生时代实现大整数的故事(评论10:"landed on a big int implementation")
性能与优化
- 建议使用XMM指令优化x86代码(评论8:"I would expect the best x86 machine code would use XMM instructions")
- 提供分割算法的论文参考(评论9:"split your 128bit integer into four 32bit integers")
不同观点保持平衡:既有对历史实现的怀旧(评论1-2),也有对现代优化的建议(评论5-6,8-9),同时包含对实用性的质疑(评论7)和个人经历分享(评论10)。技术讨论集中在除法优化、算法选择和硬件指令利用等具体实现层面。