ESP8266 运行 xtensa 内核,要从闪存读取数据,所有访问都必须使用 32 位字执行。为此,我编写了以下方法:
void memcpy_P(void * dst, const void * src, const unsigned int len)
{
char * _dst = ( char *)dst;
const char * _src = (const char *)src;
unsigned int aligned_len = len & ~0x3;
while(aligned_len > 0)
{
*(uint32_t *)_dst = *(uint32_t *)_src;
_dst += 4;
_src += 4;
aligned_len -= 4;
}
const unsigned int remainder = len & 0x3;
if (remainder > 0)
{
uint32_t tmp = *(uint32_t *)_src;
_dst[0] = (tmp & 0xFF000000) >> 24;
if (remainder > 1)
{
_dst[1] = (tmp & 0x00FF0000) >> 16;
if (remainder > 2)
_dst[2] = (tmp & 0x0000FF00) >> 8;
}
}
}
这里有什么改变可以建议提高性能吗?
注意:这是特定于平台的,永远不会在任何其他平台/架构上使用,专门针对 xtensa 内核的程序集版本在这种情况下是完全可以接受的。
编辑
根据反馈/评论和谷歌,我想出了以下内容:
void memcpy_P(void * dst, const void * src, const unsigned int len)
{
uint32_t * _dst = ( uint32_t *)dst;
const uint32_t * _src = (const uint32_t *)src;
const uint32_t * _end = _src + (len >> 2);
while(_src != _end)
*_dst++ = *_src++;
const uint32_t rem = len & 0x3;
if (!rem)
return;
const uint32_t mask = 0xFFFFFFFF << ((4 - rem) << 3);
*_dst = (*_dst & ~mask) | (*_src & mask);
}