我正在使用ARM926EJS。 在内存拷贝testing中,我没有使用Linux,所以内存速度提高了20%(就像入门可执行文件一样)。 但在Linux中,相同的代码运行速度慢了20%。
代码是
///下面的代码只是执行突发模式memcopytesting。 void asmcpy(void * a,void * b,int iSize) { 做 { asm挥发性( “ldmia%0 !, {r3-r10} \ n \ t” “stmia%0 !, {r3-r10} \ n \ t” :“+ r”(a),“+ r”(b) : : “R”(R 3), “R”(R 4), “R”(R 5), “R”(R 6), “R”(R 7), “R”(R 8), “R”(R 9), “R”(R 10) ); }而(size--) }
我validation了没有其他进程在linux上占用CPU时间(我用time命令检查了这个,它显示的实时和usr时间一样 )
请告诉我什么可以与Linux的问题?
感谢和问候。
添加:
我的testing代码是
int main() { int a [320 * 120],b [320 * 120]; for(int i = 0; i!= 10000; i ++) { ///大小除以8,因为我们的memcpy函数在迭代中执行8个整数加载存储 asmcpy(a,b,(320 * 120)/ 8); } }
入门可执行文件是一个bin文件,通过串口发送到RAM,并通过跳转到RAM中的地址直接执行。 (不需要操作系统)
添加。
我没有看到其他处理器上的性能差异。他们使用SD RAM,这个处理器使用的是DDR Ram。 这可能是一个原因吗?
添加。 数据高速caching在启动代码时没有启用,数据高速caching在Linux模式下是可用的,所以理想情况下所有的数据都应该被高速caching,并且在没有任何内存延迟的情况下进行访问,但是Linux的速度还是慢了20%。
ADDED:我的微控制器是LPC3250。 两个testing都在相同的外部DDR RAM上进行testing。
这个芯片有一个MMU,所以Linux可能用它来管理内存。 也许只是启用它引入了一些性能打击。 另外,Linux使用懒惰的内存分配策略,只在内存页面首次触发时才分配内存页面。 如果你正在复制一大块内存,MMU会产生页面错误,要求内核在你的循环内部分配一个页面。 在低端处理器上,所有这些上下文切换会导致缓存刷新,并引起明显的减速。
如果您的系统足够小,请尝试使用无MMU版本的Linux(如uClinux )。 也许它会让你使用性能相近的更便宜的芯片。 在嵌入式系统上,每一分钱都很重要。
更新:一些额外的细节:
每个Linux进程都得到它自己的内存映射,起初这只包括内核和(可能)可执行代码。 所有线性4GB(32位)的其余部分似乎都可用,但没有分配给它们的RAM页面。 一旦读取或写入未分配的内存地址,MMU就会发出页面错误并切换到内核。 内核看到它仍然有很多可用的RAM页面,因此选择一个,将其分配给故障点并返回到您的代码,从而完成中断的指令。 下一个将不会失败,因为整个页面(通常是4KB)已经分配; 但是几次迭代之后,它会碰到另一个未分配的空间,MMU将再次调用内核。
你如何执行时间? 在你的例子中没有时间码。
你确定你没有测量过程加载/卸载时间吗?
在这两种情况下,处理器的时钟速度是否一样?
如果使用外部SDRAM在两种情况下的RAM时序相同?
两种情况下都启用了数据缓存吗?
克利福德
入门不是“只是一个可执行文件”。 必须有一些代码来设置DDR控制器寄存器。
如果缓存也启用,那么MMU一定是这样。 我想在ARM926EJS上,没有MMU就不能有数据缓存。
我相信每个上下文都会导致缓存刷新,因为缓存是虚拟索引的,虚拟标记的,而且内核和用户空间不共享相同的地址空间,所以在没有操作系统的情况下,可能会有更多不需要的缓存刷新。
这里有一篇关于运行Linux时VIVT缓存刷新成本的文章
什么微控制器(不只是什么ARM CPU)你在使用?
是否有可能在非Linux运行中测试的阵列是单片机设备本身的RAM,而在Linux测试中,测试的阵列是在外部RAM中? 内部RAM通常比外部RAM快得多 – 这可能导致Linux测试速度变慢,即使数据缓存仅在Linux运行时启用。