c - 使用单个变量/寄存器存储 2 个值(并通过位掩码和/或字长的特定 CPU 指令读取它们)

标签 c algorithm gcc optimization assembly

我有一个处理数据结构的代码。

我的函数接收一个结构,并继续处理它,就像防火墙处理数据包一样:解释它的信息,甚至可能修改它或将其转换为另一种类型的数据包。 例如,函数有时会将结构转换为另一种类型的结构,然后继续;其余代码将再次根据结构的类型执行其他操作。 正如我所说,它就像一个防火墙;它可能会改变结构内容甚至整个结构类型,并会根据我们当前的结构继续执行规则。

这样,对于每个结构,有两个我将一直使用的关于它的信息,一个是相对于另一个的(总是会一起改变):结构的类型和它的大小。

我的第一个方法是使用两个变量处理结构:类型和大小。 每次我决定将一种结构转换为另一种类型时,我都会更改这两个值,然后它们继续或跳转到返回代码。

但是我的新想法是这样的:

  • 单个变量:类型。

  • 不是枚举,每个类型值都是这样定义的:

    #define MYSTRUCTTYPE__SOMETHING   (0x010000U | 200U)
    #define MYSTRUCTTYPE__OTHERTHING  (0x020000U | 310U)
    #define MYSTRUCTTYPE__LOLIMOUT    (0x030000U | 600U)
    #define MYSTRUCTTYPE__OFIDEIAS    (0x040000U | 600U) /* Yes, there are types with the same size; that's why I don't define a type value by it's size */
    #define MYSTRUCTTYPE__COSMOKRAMER (0x050000U | 400U)
    

如您所见,方法是这样的: - 每个 TYPE 值都包含它的类型和大小; - 大小是它的最低 16 位。 - 我不需要访问值的其他部分 - “类型”是整个“(somenumber|size)”。只有尺寸需要单独读取。

这样,我就不需要在每次更改结构类型时都更新 SIZE 和 TYPE。

只要设置了 Type 变量,我也会得到它的大小: - ((unsigned short)类型) - (类型 & 0xFFFFU) - 在汇编中,只需将“Type”寄存器称为“AL”部分

我想要的是提高效率:我假设生成的代码将只使用相同的寄存器,但每次我引用大小时只考虑最低的 16 位。 这对 x86 机器来说似乎没问题。 但是其他常见的架构也有等效的方法来访问寄存器的最低部分,而不修改它?

如果不是,生成的代码将具有以下等价物:

memcpy(Buff, MyStructure, (Type & 0xFFFFU));   
somewhere[(Type & 0xFFFFU)] = 243432;
printf("Hey man! I have %u bytes!\n", ((unsigned int)Type & 0xFFFFU));

...

如果机器没有只读取寄存器最低 16 位的指令,操作 (Type & 0xFFFFU) 将被插入我之前使用“Size”变量的任何地方,这样,它会增加代码大小。

(A) 您认为这是一种好的方法/算法吗?

(B) 即使机器没有这种指令,每次都必须执行“(Type & 0xFFFFU)”,它是否仍然比使用 2 个变量更好?

注意: - 我对此作为代码优化很感兴趣,我知道为了获得 0.00000000us 的速度而关心那些小细节是一个坏主意。但我正在处理 Linux 内核级别的这个特定程序,或 3d 游戏引擎,或任何实时代码,人们会花更多时间让它变得更好。 - 对不起,我的英语真的很糟糕。 - 对不起,如果它混淆了,我编辑了很多次,我不知道我的解释是否对你有意义。

最佳答案

您可以使用结构实现所有这些:

struct header {
    short id;
    short size;
};

struct message {
    struct header header;
    char* payload;
};

static const struct header  SOMETHING = {0x01, 200};
static const struct header OTHERTHING = {0x02, 310};

void transform(struct message* message) {
    if(message->header.id == SOMETHING.id) {
        message->header = OTHERTHING;
    }
}

您要做的实际上是实现您自己的结构。目前尚不清楚写入+按位运算是否比两次写入更快。将该工作留给编译器。它比你更了解底层系统,更有可能生成更好的程序集。

它也不会使您的代码更清晰。您一定会在其中一个按位运算中犯错误。

关于c - 使用单个变量/寄存器存储 2 个值(并通过位掩码和/或字长的特定 CPU 指令读取它们),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27761373/

相关文章:

c - 链接 SDL2 在 OSX 上发出无数链接错误

c++ - 快速提问 : explain this typedef

c - 为什么这个质因数分解算法有缺陷却给出了正确的答案?

algorithm - 关键系统是否有任何软件保证?

c++ - 带有 std::function 的通用 lambda 不捕获变量

c - 在 C 中将 Buffer 传递给结构体

arrays - 当有无限 CAMPU 时,比较两个数组的最佳方法是什么?

c++ - 这个指针和所有参数在调用后都是空的(但之前没问题)

c - C中有符号和无符号整数的按位非

c++ - 设置 3d 空间中对象的方向