3

我有一个与性能相关的问题。比方说,我有某种结构,比如这个:

typedef struct
{
    uint8_t FirstSofRec     :1;     //SOF byte
    uint8_t SecSofRec       :1;     //SOF byte
    uint8_t RecPending      :1;     //Pending flag
    uint8_t Timeout         :1;     //Timeout flag
    uint8_t RecCompleted    :1;     //Recievein completed flag
    uint8_t CrcMatch        :1;     //CRC match flag
    uint8_t DataLength      :2;     //Data length field (1 - 8)
}Reciever_flags_t;

typedef struct  
{
    Reciever_flags_t flags;
    uint8_t SofFrame[2];
    uint8_t MsgBuffer[MAX_REC_BUFF_SIZE];
    uint8_t CRC;
}Reciever_struct_t;

将一个结构的内容复制到另一个结构的最快(在性能意义上,编写嵌入式代码)方法是什么?

我有以下选择:

直接指针使用:

Reciever_struct_t BASE;
Reciever_struct_t COPY;
Reciever_struct_t *PtToBase = &BASE;
Reciever_struct_t *PtToCopy = ©

*PtToCopy = *PtToBase

或者使用 uint8 指针并逐字节复制它(假设结构中没有挂起,并且我们知道它的大小)

Reciever_struct_t BASE;
Reciever_struct_t COPY;
uint8_t *CpyPtrBase = (uint8_t *)&BASE;
uint8_t *CpyPtrCopy = (uint8_t *)©

while(SizeIsNotZero--)
{
*CpyPtrCopy++ = *CpyPtrBase++
}

这个问题的主题不是关于 malloc 和 ect 之类的细节,而是关于想法。感谢您的建议,最好的问候!

4

3 回答 3

8

简单的结构赋值:

COPY = BASE ;

或者

*PtToCopy = *PtToBase ;

将由编译器生成的代码提供,因此将针对目标和您设置的编译器选项进行优化。

高级编码的逐字节复制可能同样快,但不可能更快。除了 8 位架构之外,它可能会更慢。

比字节复制更好的方法是:

memcpy( PtToCopy, PtToBase, sizeof(*PtToCopy) ) ;

要不就:

memcpy( &COPY, &BASE, sizeof(COPY) ) ;

但这依赖于库函数的实现,memcpy()它可能与编译器为分配生成的函数相同也可能不同,但也可能针对目标进行优化,但不会考虑编译器设置,因为它是预编译的。

如果您真的需要知道,请在目标上对其进行基准测试,或检查编译器生成的汇编代码,但我怀疑这是一种“微优化”,通过考虑您的代码设计,您可能会获得更好的性能提升更高的更整体或抽象的层次。更大的性能提升往往来自于设计有效的数据结构和完全避免复制数据的方法。

于 2013-09-21T07:52:53.650 回答
2

前者可能更有效,因为编译器可以使用特定 CPU 可能的最大数据类型进行复制。结构将在对齐重要的平台上具有结构填充,因此前一种方法可以利用这一点。

后者可能会也可能不会那么有效,这取决于编译器在优化方面的能力。

虽然如果您关心性能,最明智的做法可能是使用 memcpy(),因为它将针对特定系统进行大量优化。

唯一可以确定的方法是进行基准测试。

于 2013-09-20T21:01:58.557 回答
0

前一种方式会更快,因为编译器将有足够的信息使其尽可能快(隐式循环不是这种情况)。或者,您可以使用 memcpy,但我怀疑它会更快。

于 2013-09-20T20:58:02.777 回答