我有一个与绩效相关的问题。比方说,我有一种结构,就像这样:
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
或者使用let说的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这样的细节,只是关于想法。感谢您的建议,最好的问候!
答案 0 :(得分:8)
简单的结构分配:
COPY = BASE ;
或
*PtToCopy = *PtToBase ;
将由编译器生成的代码提供,因此将针对目标和您设置的编译器选项进行优化。
高级编码的逐字节拷贝可以快速,但是更快是不可能的。除了8位架构外,它可能会更慢。
比字节副本更好的方法是:
memcpy( PtToCopy, PtToBase, sizeof(*PtToCopy) ) ;
或只是:
memcpy( ©, &BASE, sizeof(COPY) ) ;
但是它依赖于库函数memcpy()
的实现,它可能与编译器为赋值生成的函数相同或不同,但也可能针对目标进行优化,但是赢了不考虑编译器设置,因为它是预编译的。
如果你真的需要知道,在目标上对它进行基准测试,或者检查编译器生成的汇编程序代码,但我怀疑这是一个“微优化”,你可能会考虑到你的性能提升。更高整体或更抽象的代码设计。通过设计有效的数据结构和避免完全复制数据的方法,可以获得更大的性能提升。
答案 1 :(得分:2)
前者可能更有效,因为编译器可以使用特定CPU可能的最大数据类型进行复制。结构将在平台上具有结构填充,其中对齐很重要,因此前一种方法可以利用它。
后者可能也可能不那么有效,这取决于编译器在优化方面的优势。
虽然如果你担心性能,最明智的可能是使用memcpy(),因为它将针对特定系统进行大量优化。
唯一可以确定基准的方法。
答案 2 :(得分:0)
前一种方式会更快,因为编译器将有足够的信息使其尽可能快(不是隐式循环的情况)。或者,您可以使用memcpy,但我怀疑它会更快。