【问题标题】:Most efficient way to compare two __int64 numbers and get -1,0,1比较两个 __int64 数字并得到 -1,0,1 的最有效方法
【发布时间】:2010-07-06 00:54:11
【问题描述】:

我一直在努力解决一个非常简单的问题...我正在使用 AVL 树处理 4 维立方体...现在问题是与性能相关的问题...基本上我必须比较数十亿个 64 位数字...(因为我的密钥是 64 位,包括 4 个维度,每个维度为 16 位)...

问题不在于我无法比较 2 个 64 位数字,而是我需要在尽可能少的时钟周期内进行比较。

不幸的是,我的 AVL 树模板的签名是“int CompareKeyNode(key k, handle h)”

在后台我有两个 __int64 数字 lhs 和 rhs,不幸的是这种方法的合同是: 1. lhs==rhs 返回 0 2. lhs > rhs 返回 1 3. lhs

现在,如果上述方法需要一个 __int64 数字,我可以简单地执行 (METHOD A) return lhs - rhs;

不幸的是,它只需要一个 32 位整数,所以我不得不求助于类似于 ((METHOD B)) 的东西,即。返回 lhs == rhs ? 0 : (lhs

我的问题是使用 (METHOD A) 加载我的数据需要 60 秒,而 (METHOD B) 需要 117 秒。

不幸的是,(方法 A)不正确,因为它在转换 lhs-rhs 语句的返回时会丢失精度。

处理时间对我来说至关重要,我相信现在一定有一个简单有效的答案正在逃避我......

有人知道如何解决这个问题吗?或者有什么建议?

我在 VC++(非托管)中工作,但 .NET/Java 肯定已经在 J​​ITing/VM 阶段解决了这个问题......否则它们会受到巨大的性能影响。

PS:已经尝试过 memcmp() 但还不够好...

【问题讨论】:

    标签: int64


    【解决方案1】:

    在汇编中,减去它们。
    零标志设置 = 0
    携带标志集 = -1
    否则 1

    【讨论】:

    • 如果速度是这样一个问题,实际上可能值得内联汇编 - C++ 允许这样做。例如,*** codeproject.com/KB/cpp/edujini_inline_asm.aspx *** 如果当然你可能必须学习汇编。然后您可能还会发现,在完成所有工作之后它并没有那么快!
    • @MarineHero:有什么原因你不能为此添加一些内联汇编吗?
    • 是否有一个常见的情况——例如,多数相等,只有少数 -1 或 +1?确保这是第一个。您可能无法比比较平等更快!可能会尝试重新安排其他事情以提高效率,分治多线程等。当然所有这些都是肮脏的修复。
    • FastAI:下面的汇编 101 代码现在可以在 72 秒内加载我的数据!发送! static int compare_key_node(key k, handle h) { _asm { mov eax,dword ptr [h] mov ecx,dword ptr [k] sub ecx,dword ptr [eax+10h] mov edx,dword ptr [ebp+0Ch] sbb edx,dword ptr [eax+14h] mov eax,ecx jz eql jc nga mov eax,1 jmp xxx eql: mov eax,0 jmp xxx nga: mov eax, -1 xxx: } }
    【解决方案2】:

    你可以试试(lhs<rhs) - (rhs<lhs)。不能保证它会带来改进(完全),但至少可能它可能...

    【讨论】:

    • 现在为什么我没有想到...有效,但仍然比我拥有的更糟糕...需要 130 秒,而我目前的 117 秒。
    • @MarineHero:我想这并不让我感到惊讶——大多数编译器并没有在优化“奇怪”代码方面投入太多精力,这绝对是......
    【解决方案3】:

    我真的只能看到你应该重载或重写函数以接受 __int64。像这样的内联逻辑总是会导致性能损失。为什么不能重载你的类来接受 __int64?

    【讨论】:

    • 当然...但是...我不能这样做,原因如下: 1. 我在不同的地方使用基于相同模板的 AVL 树 2. 我不想强加进入 AVL 类的 64 位开销,因为这比我的关键比较更重要。
    猜你喜欢
    • 2011-01-19
    • 1970-01-01
    • 2014-05-15
    • 1970-01-01
    • 1970-01-01
    • 2013-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多