【发布时间】:2012-04-30 18:48:54
【问题描述】:
对于我正在从事的业余项目,我需要在 x86 CPU 上模拟某些 64 位整数运算,并且它需要快速。
目前,我正在通过 MMX 指令执行此操作,但这真的很痛苦,因为我必须一直刷新 fp 寄存器状态(而且因为大多数 MMX 指令处理 已签名 整数,我需要无符号行为)。
所以我想知道这里的 SSE/优化专家是否可以使用 SSE 提出更好的实现。
我需要的操作如下(非常具体):
uint64_t X, Y;
X = 0;
X = 1;
X << 1;
X != Y;
X + 1;
X & 0x1 // get lsb
X | 0x1 // set lsb
X > Y;
具体来说,我不需要通用的加法或移位,例如,只需加一和左移一。真的,只是这里显示的精确操作。
当然,除了在 x86 上,uint64_t 是通过使用两个 32 位标量来模拟的,这很慢(而且,在我的情况下,根本不起作用,因为我需要加载/存储是原子的,在加载/存储两个单独的寄存器时它们不会是这样)。
因此,我需要 SIMD 解决方案。
其中一些操作很简单,SSE2 已经支持。其他人(!= 和 <)需要更多的工作。
建议? SSE 和 SSE2 都很好。允许 SSE3 需要一些说服力,而 SSE4 可能是不可能的(支持 SSE4 的 CPU 很可能运行 64 位无论如何,所以我不需要这些变通办法)
【问题讨论】:
-
SSE2 直接支持 64 位整数加法。我假设您还需要 64 位乘法? 64 x 64 -> 64 位(下半部分),还是需要 64 x 64 -> 128 位?
-
不需要乘法,只是我上面显示的特定操作(所以甚至不是一般的加法,只是增加 1。是的,加法是由 SSE2 提供的,但我想我不妨只是为了完整起见,显示我需要的所有操作。只是意味着其中一些很简单:)
-
如果您使用的 CPU 不能处理 64 位但支持 SSE2,那么这将是 Athlon XP、Pentium III 或更旧的 Pentium IV。在 Athlon XP 的情况下,我根本不会期望任何性能提升,因为它确实将每个 SSE 操作拆分为两个 64 位操作,然后分别执行。对于 Pentium III - 我不知道。对于 Pentium IV,您可能会获得一些加速 - 取决于从和向通用注册器传输的频率,因为这些在此硬件上的速度非常慢。
-
@drhirsch 我不知道你想表达什么观点。你只是因为无聊而吹毛求疵吗?是的,我知道操作系统不限制可用的 SSE 指令集。而我自己的机器是运行在 64 位操作系统上的 i7。但我希望我的代码也能在其他计算机上运行,包括那些由于操作系统或 CPU 限制为 32 位代码的计算机。并且依靠,比如说,SSE4.2 将切断大多数 32 位计算机。依靠 SSE2 几乎可以涵盖所有这些。现在,你有什么相关的要贡献的吗?
-
你为什么不这样写你的问题?就目前而言,听起来您需要在 CPU 上进行 64 位操作,而该 CPU able 无法在 64 位模式下运行 - 有点旧。
标签: c++ optimization x86 64-bit sse