C语言 比较 32 位微控制器上的两个 64 位变量



我有以下问题:我有两个64位变量,必须尽快比较它们,我的微控制器只有32位。

我的想法是有必要将 64 位变量分成两个 32 位变量,就像这样

uint64_t var = 0xAAFFFFFFABCDELL;
hiPart = (uint32_t)((var & 0xFFFFFFFF00000000LL) >> 32);
loPart = (uint32_t)(var & 0xFFFFFFFFLL);

然后比较hiParts和loParts,但我确信这种方法很慢,并且有更好的解决方案

第一条规则应该是:编写你的程序,以便人类可以读

当有疑问时,不要假设任何事情,而是要衡量它。让我们看看,神电给了我们什么。

#include <stdint.h>
#include <stdbool.h>
bool foo(uint64_t a, uint64_t b) {
return a == b;
}
bool foo2(uint64_t a, uint64_t b) {
uint32_t ahiPart = (uint32_t)((a & 0xFFFFFFFF00000000ULL) >> 32);
uint32_t aloPart = (uint32_t)(a & 0xFFFFFFFFULL);
uint32_t bhiPart = (uint32_t)((b & 0xFFFFFFFF00000000ULL) >> 32);
uint32_t bloPart = (uint32_t)(b & 0xFFFFFFFFULL);
return ahiPart == bhiPart && aloPart == bloPart;
}

 

foo:
eor     r1, r1, r3
eor     r0, r0, r2
orr     r0, r0, r1
rsbs    r1, r0, #0
adc     r0, r0, r1
bx      lr
foo2:
eor     r1, r1, r3
eor     r0, r0, r2
orr     r0, r0, r1
rsbs    r1, r0, #0
adc     r0, r0, r1
bx      lr

如您所见,它们会产生完全相同的汇编代码,但您决定,哪一个更不容易出错且更容易阅读?

几年前有一段时间,你需要做一些技巧才能比编译器更聪明。但是在 99.999% 的情况下,编译器会比你更聪明。

而且您的变量是无符号的。所以使用ULL而不是LL.

最快的方法是让编译器来做。大多数编译器在微优化方面比人类好得多。

uint64_t var = …, other_var = …;
if (var == other_var) …

没有太多方法可以做到这一点。在后台,编译器将安排将每个变量的高 32 位和低 32 位加载到寄存器中,并比较包含高 32 位的两个寄存器和包含低 32 位的两个寄存器。程序集代码可能如下所示:

load 32 bits from &var into r0
load 32 bits from &other_var into r1
if r0 != r1: goto different
load 32 bits from &var + 4 into r2
load 32 bits from &other_var + 4 into r3
if r2 != r3: goto different
// code for if-equal
different:
// code for if-not-equal

以下是编译器比您更了解的一些事情:

  • 使用哪个寄存器,基于周围代码的需要。
  • 是重复使用相同的寄存器来比较上部和下部,还是使用不同的寄存器。
  • 是先处理一个部分,然后再
  • 处理另一个部分(如上所述(,还是先加载一个变量,然后再加载另一个变量。最佳顺序取决于寄存器的压力以及特定处理器型号的内存访问时间和流水线。

如果您使用工会,您可以比较Hi和Lo Part,而无需任何额外的计算:

typedef union
{
struct
{    
uint32_t   loPart;
uint32_t   hiPart;
};
uint64_t       complete;
}uint64T;
uint64T var.complete = 0xAAFFFFFFABCDEULL;

最新更新