我遇到以下问题:我有两个64位变量,必须尽快比较它们,我的微控制器只有32位。
我的想法是,有必要像这样将64位变量分为两个32位变量
uint64_t var = 0xAAFFFFFFABCDELL;
hiPart = (uint32_t)((var & 0xFFFFFFFF00000000LL) >> 32);
loPart = (uint32_t)(var & 0xFFFFFFFFLL);
然后比较hiParts和loParts,但是我确信这种方法很慢并且有更好的解决方案
答案 0 :(得分:3)
第一个规则应该是:编写您的程序,以便人类可以阅读。
如有疑问,请不要假设任何东西,而要进行测量。让我们看看godbolt给我们带来了什么。
#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
如您所见,它们会产生完全相同的汇编代码,但是您可以决定哪个更不容易出错并且更容易阅读?
答案 1 :(得分:1)
几年前的某个时候,您需要做一些技巧,以使其比编译器更聪明。但是在99.999%的情况下,编译器将比您更聪明。
并且您的变量是无符号的。因此,请使用ULL
而不是LL
。
答案 2 :(得分:1)
最快的方法是让编译器执行此操作。大多数编译器在微观优化方面比人类要好得多。
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
以下是编译器比您更了解的一些内容:
答案 3 :(得分:0)
如果您使用工会,则可以在不进行任何额外计算的情况下比较“高”和“低”零件:
typedef union
{
struct
{
uint32_t loPart;
uint32_t hiPart;
};
uint64_t complete;
}uint64T;
uint64T var.complete = 0xAAFFFFFFABCDEULL;