我正在使用ARM926EJS。我在内存复制测试中的内存速度提高了20%,没有Linux(就像入门可执行文件一样)。但在linux中,相同的代码运行速度要慢20%。
代码是
/// Below code just performs burst mode memcopy test. void asmcpy(void *a, void *b, int iSize) { do { asm volatile ( "ldmia %0!, {r3-r10} \n\t" "stmia %0!, {r3-r10} \n\t" :"+r"(a), "+r"(b) : :"r"(r3),"r"(r4),"r"(r5),"r"(r6),"r"(r7),"r"(r8),"r"(r9),"r"(r10) ); }while(size--) }
我确认没有其他进程在Linux上占用CPU时间。(我使用time命令检查了这一点,它显示实时与 usr time 相同)
请告诉我linux有什么问题?
谢谢&问候。
增加:
我的测试代码是
int main() { int a[320 * 120], b[320 * 120]; for(int i=0; i != 10000; i++) { /// Size is divided by 8 because our memcpy function performs 8 integer load stores in the iteration asmcpy(a, b, (320 * 120) / 8); } }
Getting Started可执行文件是一个bin文件,它使用串行端口发送到RAM,并通过跳转到RAM中的该地址直接执行。 (不需要操作系统)
ADDED。
我没有在其他处理器上看到这样的性能差异。他们使用的是SD RAM,这款处理器使用的是DDR Ram。这可能是一个原因吗?
溶液。 启动代码时未启用数据缓存,并且在Linux模式下启用了数据缓存,因此理想情况下,所有数据都应缓存并在没有任何RAM延迟的情况下进行访问,但Linux的速度仍为20%。
增加: 我的微控制器是LPC3250。两个测试都在相同的外部DDR RAM上进行了测试。
答案 0 :(得分:10)
这款芯片有一个MMU,因此Linux可能会用它来管理内存。也许只是启用它会引入一些性能影响。此外,Linux使用延迟内存分配策略,仅在首次命中时将内存页分配给进程。如果您正在复制大量内存,MMU将生成页面错误,要求内核在循环内部分配页面。在低端处理器上,所有这些上下文切换都会导致缓存刷新并引入明显的减速。
如果您的系统足够小,请尝试使用无MMU版本的Linux(如uClinux)。也许它会让你使用性价比更低的芯片。在嵌入式系统上,每一分钱都很重要。
更新:一些额外的细节:
每个Linux进程都获得自己的内存映射,首先这只包括内核和(可能)可执行代码。所有其余的线性4GB(32位)似乎都可用,但没有分配RAM页面。一旦读取或写入未分配的内存地址,MMU就会发出页面错误信号并切换到内核。内核看到它仍然有很多空闲的RAM页面,所以选择一个,将它分配给故障点并返回到你的代码,完成中断的指令。下一个不会失败,因为整个页面(通常是4KB)已经分配;但是稍后会进行几次迭代,它会击中另一个未分配的空间,MMU会再次调用内核。
答案 1 :(得分:3)
你是如何进行计时的?您的示例中没有计时代码。
您确定没有测量过程加载/卸载时间吗?
两种情况下处理器的时钟速度是否相同?
如果使用外部SDRAM,RAM时序在两种情况下都相同吗?
两种情况下都启用了数据缓存吗?
克利福
答案 2 :(得分:2)
入门并非“只是一个可执行文件”。必须有一些代码来设置DDR控制器寄存器。
如果还启用了缓存,则必须是MMU。我认为在ARM926EJS上,没有MMU就无法拥有数据缓存。
我相信每个上下文切换都会导致缓存刷新,因为缓存是虚拟索引,虚拟标记,内核和用户空间不共享相同的地址空间,所以你可能有更多不需要的缓存刷新OS。
这是一个paper,其中包含运行Linux时VIVT缓存刷新成本的一些方面
答案 3 :(得分:1)
您使用的是哪种微控制器(不仅仅是ARM CPU)?
在非Linux运行中,您正在测试的阵列是否可能是微控制器设备本身的RAM,而在Linux测试中,正在测试的阵列是在外部RAM中?内部RAM的访问速度通常比外部RAM快得多 - 这可能导致Linux测试速度变慢,即使只为Linux运行启用了数据缓存。