我正在尝试在C中实现一个简单,适度高效的bignum库。我想使用它编译的系统的完整寄存器大小来存储数字(大概是32或64位整数)。我的理解是我可以使用intptr_t来完成这个。它是否正确?是否有更符合语义的类型,例如intword_t?
我也知道,通过GCC,我可以轻松地在32位机器上进行溢出检测,将两个参数向上转换为64位整数,这将占用两个寄存器并利用IA31 ADC(带进位)等指令。我可以在64位机器上做类似的事情吗?是否有一个128位类型,我可以编译,如果它们可用,将编译使用这些指令?更好的是,是否有一个标准类型,表示两倍的寄存器大小(如intdoubleptr_t)所以这可以以独立于机器的方式完成?
谢谢!
答案 0 :(得分:1)
我强烈建议您使用C99 <stdint.h>
标头。它声明了int32_t
,int64_t
,uint32_t
和uint64_t
,它们看起来就像您真正想要使用的那样。
编辑:正如Alok指出的那样,int_fast32_t
,int_fast64_t
等可能就是您想要使用的。您指定的位数应该是数学运算所需的最小位数,即计算不会“翻转”。
优化来自这样一个事实:CPU不必浪费周期重新排列数据,填充读取的前导位,以及在写入时进行读取 - 修改 - 写入。事实是,许多处理器(例如最近的x86s)在CPU中都有硬件可以很好地优化这些访问(至少是填充和读取 - 修改 - 写入部分),因为它们非常常见且通常只涉及到处理器和缓存。
因此,您唯一要做的就是确保访问是对齐的:使用sizeof(int_fast32_t)
或其他任何内容并使用它来确保缓冲区指针与之对齐。
事实是,这可能不会带来那么大的改进(由于运行时硬件优化传输),所以写一些东西并计时它可能是确定的唯一方法。此外,如果你真的对性能感到沮丧,你可能需要查看SSE或AltiVec或者你的处理器所具有的任何矢量化技术,因为它会超越你在编写数学时可以编写的任何可编写的东西。
答案 1 :(得分:1)
有什么理由不使用size_t? size_t在32位系统上是4个字节,在64位系统上是8个字节,并且可能比使用WORD_SIZE更便携(我认为WORD_SIZE是特定于gcc的,不是吗?)
我不知道64位系统上有任何128位值,这里可能是错误的,但在内核或常规用户应用程序中没有遇到过这种类型。