Linux 嵌入式 (ARM) 中的低内存吞吐量
Posted
技术标签:
【中文标题】Linux 嵌入式 (ARM) 中的低内存吞吐量【英文标题】:Low Memory throughput in Linux-Embedded ( ARM ) 【发布时间】:2009-09-09 14:42:04 【问题描述】:我正在使用 ARM926EJS。在没有 Linux 的情况下,我在内存复制测试中的内存速度提高了 20%(就像入门可执行文件一样)。但在 linux 中,同样的代码运行速度要慢 20%。
代码是
/// 下面的代码只是执行突发模式的内存复制测试。 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"(r3),"r"(r4),"r"(r5),"r"(r6),"r"(r7),"r"(r8),"r"(r9), “r”(r10) ); 而(大小--)我确认没有其他进程在 linux 上占用 CPU 时间。(我使用 time 命令检查了这一点,它显示 real time 与 usr time 相同)
请告诉我linux有什么问题?
感谢和问候。
添加:
我的测试代码是
主函数() int a[320 * 120],b[320 * 120]; for(int i=0; i != 10000; i++) /// 大小除以 8 因为我们的 memcpy 函数在迭代中执行了 8 个整数加载存储 asmcpy(a, b, (320 * 120) / 8);Getting Started 可执行文件是一个 bin 文件,它使用串行端口发送到 RAM,并通过跳转到 RAM 中的该地址直接执行。 (无需操作系统)
添加。
我没有在其他处理器上看到这样的性能差异。他们使用的是 SD RAM,这个处理器使用的是 DDR Ram。会是原因吗?
已添加。 入门代码中未启用数据缓存,并且在 Linux 模式下启用了数据缓存,因此理想情况下,所有数据都应被缓存并在没有任何 RAM 延迟的情况下访问,但 Linux 仍然慢 20%。
添加: 我的微控制器是 LPC3250。两项测试均在相同的外部 DDR RAM 上进行了测试。
【问题讨论】:
您能在两种不同的设置上发布您的测试代码和场景吗?还有什么是入门可执行文件?总的来说,只是稍微详细一点,可能有很多不同的原因 这里的性能比较几乎是苹果与橘子的比较,因为您运行的是一个完整的操作系统,该操作系统具有计时器滴答声、内存管理等,所有这些都计划运行,而没有操作系统只是运行直接指令。我认为这几乎可以解释您的性能差异。就像哈维尔说的那样,即使内核上没有其他用户进程,它自己仍然可以做很多事情。 我有一个类似的硬件(ARM926EJS + DDR),我观察到完全相反:没有操作系统,内存操作太慢了,直到缓存被激活(即在操作系统中) 像我一样使用突发模式 RAM 访问,使用 LDMIA 和 STMIA 来提高速度。 【参考方案1】:这个芯片有一个 MMU,所以 Linux 很可能用它来管理内存。也许只是启用它会带来一些性能损失。此外,Linux 使用惰性内存分配策略,仅在第一次访问进程时才将内存页分配给它。如果您要复制一大块内存,MMU 将生成页面错误以要求内核在循环内分配页面。在低端处理器上,所有这些上下文切换都会导致缓存刷新并显着降低速度。
如果您的系统足够小,请尝试无 MMU 版本的 Linux(如 uClinux)。也许它会让你使用性能相似的更便宜的芯片。在嵌入式系统上,每一分钱都很重要。
更新:一些额外的细节:
每个 Linux 进程都有自己的内存映射,起初这仅包括内核和(也许)可执行代码。所有其余的线性 4GB(32 位)似乎都可用,但没有分配给它们的 RAM 页面。一旦您读取或写入未分配的内存地址,MMU 就会发出页面错误信号并切换到内核。内核发现它仍然有很多空闲的 RAM 页面,因此选择一个,将其分配给故障点并返回到您的代码,从而完成中断的指令。下一个不会失败,因为已经分配了整个页面(通常为 4KB);但是几次迭代之后,它会碰到另一个未分配的空间,MMU 会再次调用内核。
【讨论】:
嗨哈维尔,我只在内存之间进行内存复制。那么页面错误是如何发生的呢?我正在使用堆栈上分配的 153KB 内存进行 memcopy。我正在循环运行它 10,000 次。 所有 RAM 都是内存管理的,因此随时可能发生故障。查看更新。 嗯... 300KB 只是几页,在第一页之后,所有的空间都应该被映射,所以你不应该再出错了。如上所述,一些简单的 MMU 在处理管道上引入了另一个步骤,并且可能仅仅因为它们处于活动状态而影响性能,即使不再产生故障。 另一个问题,即使你说'没有其他进程正在占用 CPU 时间',你总是有计时器滴答声和少数内核线程。检查 /proc/你是如何进行计时的?您的示例中没有计时代码。
您确定您没有测量进程加载/卸载时间吗?
两种情况下的处理器时钟速度是否相同?
如果使用外部 SDRAM,两种情况下的 RAM 时序是否相同?
两种情况下都启用数据缓存吗?
克利福德
【讨论】:
“时间”系统命令是否返回正确的数字?它可能配置错误。当你得到这样奇怪的结果时,一个不错的选择是让程序根据它的计时器每隔一分钟打印出几件事,然后用物理时钟(或秒表)给它们计时。 数据缓存在获取状态模式下被禁用。将使用秒表并让您知道,谢谢。【参考方案3】:入门不仅仅是“一个可执行文件”。必须有一些代码来设置 DDR 控制器寄存器。
如果缓存也被启用,那么 MMU 也必须如此。我认为在 ARM926EJS 上,没有 MMU 就没有数据缓存。
我相信每次上下文切换都会导致缓存刷新,因为缓存是虚拟索引的,虚拟标记的,并且内核和用户空间不共享相同的地址空间,所以你可能有更多不需要的缓存刷新比没有操作系统。
这是一个paper,其中涉及到运行 Linux 时 VIVT 缓存刷新的成本
【讨论】:
【参考方案4】:您使用的是什么微控制器(不仅仅是什么 ARM CPU)?
在非 Linux 运行中,您正在测试的阵列是否有可能是微控制器设备本身的 RAM,而在 Linux 测试中,正在测试的阵列是否在外部 RAM 中?内部 RAM 的访问速度通常比外部 RAM 快得多 - 这可能是导致 Linux 测试速度较慢的原因,即使仅为 Linux 运行启用数据缓存也是如此。
【讨论】:
嗨迈克尔,我的微控制器是 LPC3250。这两个数据都在相同的外部 DDR RAM 上进行了测试。以上是关于Linux 嵌入式 (ARM) 中的低内存吞吐量的主要内容,如果未能解决你的问题,请参考以下文章
嵌入式 linux基于arm中,其中的 内存映射 是啥意思?具体完成啥过程?一定采纳