C 复杂结构的指针复制

C 复杂结构的指针复制,c,performance,pointers,embedded,C,Performance,Pointers,Embedded,我有一个与性能相关的问题。比如说,我有一个结构,像这样: 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 uint

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

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指针,一个字节一个字节地复制它(假设结构中没有挂起,并且我们知道它的大小)


这个问题的主要主题不是像malloc和ect这样的细节,而是想法。谢谢你的建议,致以最良好的问候

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

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

后者可能有效,也可能无效,这取决于编译器的优化能力

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


唯一确定的方法是基准测试。

简单结构赋值:

COPY = BASE ;

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

一个高级编码的逐字节复制可能同样快,但不可能更快。在除8位体系结构之外的所有体系结构上,速度可能较慢

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

memcpy( PtToCopy, PtToBase, sizeof(*PtToCopy) ) ;
或者只是:

memcpy( &COPY, &BASE, sizeof(COPY) ) ;
但这取决于库函数
memcpy()
的实现,该函数可能与编译器为赋值生成的函数相同,也可能不同,但可能会针对目标进行优化,但不会考虑预编译时的编译器设置


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

您也可以放弃前者中的指针,而只需
COPY=BASE什么是
SizeIsNotZero
?@wildplasser-结构的大小。我们如何获得它,没关系:)在这种情况下,它将是1(标志)+2(SofFrame)+MAX_REC_BUFF_SIZE+1(CRC)。它的值应该是递减的,忘记了这一点,在代码中进行了更正。“前者”是指指针方法吗?对不起,我不是以英语为母语的人,我不懂那种形式;)但是海伊,谢谢你的回答@user2759473:不是“指针方法”,您获取地址,分配给指针,然后取消引用该指针只是分配“COPY=BASE”的一种冗长而迂回的方法。
memcpy()
不太可能比分配更好。编译器生成的代码将同样针对目标进行优化,如果库是为公共基础架构构建的,并且目标具有库不利用的功能,则可能会更好。
memcpy( PtToCopy, PtToBase, sizeof(*PtToCopy) ) ;
memcpy( &COPY, &BASE, sizeof(COPY) ) ;