+ -
当前位置:首页 → 问答吧 → 程序运行速度疑问

程序运行速度疑问

时间:2010-10-25

来源:互联网

程序如下:

*(volatile short *)(Bankaddr)=1;
*(volatile short *)(Bankaddr)=0;

这段对外设地址访问的程序,在驱动程序里面的速度和在应用程序里面的速度相差一倍
在应用程序里,外设地址是通过mmap映射的
在驱动程序里,外设地址是通过ioremap映射的,
(我将访问外设的时序参数设定的一样。并且编译应用程序时,带上了优化参数O2,
  将驱动程序和应用程序反汇编,代码也差不多,没有什么太大区别)

为何驱动程序运行的速度要比应用程序快一倍左右呢,(我是通过示波器测量数据总线发现的)
(目标板是linux2.6.31+s3c6410)

作者: zhangxujun1981   发布时间: 2010-10-25

本帖最后由 snail_314 于 2010-10-25 11:19 编辑

回复 zhangxujun1981




QUOTE:
    (我是通过示波器测量数据总线发现的)



看到信号从高到低的时间差不一样?

你mmap打开的文件不会是/dev/mem吧?

作者: snail_314   发布时间: 2010-10-25

本帖最后由 zhangxujun1981 于 2010-10-25 11:41 编辑

两个都看了,WE (WR)和data 时间.
也就是驱动程序对外设地址写的速度快一倍.

作者: zhangxujun1981   发布时间: 2010-10-25

本帖最后由 zhangxujun1981 于 2010-10-25 11:42 编辑

我是打开的文件/dev/mem,然后通过mmap映射物理地址的,测量结果是多的,就是速度慢.

未命名.JPG (12.28 KB)

下载次数:0

2010-10-25 11:31

作者: zhangxujun1981   发布时间: 2010-10-25

回复 zhangxujun1981

每次慢的差值都是1倍的样子么?还是有多种情况?有没有用户态下面的那个,不再出现1的情况?

作者: snail_314   发布时间: 2010-10-25

本帖最后由 zhangxujun1981 于 2010-10-25 13:24 编辑

我的程序像这样:

for(i=0;i<9000000;i++){
                (*(volatile short *)(GBankAddr)=0);
                (*(volatile short *)(GBankAddr)=1);
                (*(volatile short *)(GBankAddr)=0);
                (*(volatile short *)(GBankAddr)=1);
                (*(volatile short *)(GBankAddr)=0);
                (*(volatile short *)(GBankAddr)=1);
}

然后用示波器测量数据总线和WE信号,(在内核态和用户态分别运行这段程序),发现内核态(驱动程序)输出的频率是用户态的两倍,
每次都是这样,结果很一直致.我想是不是内核态的代码运行环境有什么优化和加速,例如打开了什么cache之类.

另外我发现类似 for(i=0;i<50;i++)这样不需要访问外设的指令速度运行的很快,一条指令大概几ns,
像(*(volatile short *)(GBankAddr)=0)这种指令就需要1百多ns,(将外部总线时序不算在里面,外部总线的访问时序只占有40ns,
我根据芯片资料将总线时序参数配置成这样的,而且示波器量出的结果也是对的,就是指令执行的时间太长也许是地址取值太长等).

作者: zhangxujun1981   发布时间: 2010-10-25

回复 zhangxujun1981


    arm的细节记不清楚了.大致这么解释

kernel mode时,ioremap本身是non-cache的,即所有store指令通过tlb直接出入cpu外部的bus.
但user mode时,你用的mmap访问/dev/mem,如果没错的话,/dev/mem的driver为你作的cached mapping.即你的store指令通过tlb不是出的cpu外部的bus,而是总是先写到cache中,直到下一条写往同样的地址的指令被执行,这时前一条cache中的数据才被刷新到bus上.慢就慢在这里.

就好像用户态时:
*address = 0;----
*address = 1;    |
*address = 0;---------直到这时,1才被update到bus上.
*address = 1;

作者: snail_314   发布时间: 2010-10-25

谢谢你的提示,我该怎样做,才能使用户态操作外设的速度与内核一样快呢?
(因为我的程序应用比较特殊,如果通过调用驱动程序操作外设,调用过程本身也很浪费时间,一个简单的调用
大约是400ns,速度也很慢)

作者: zhangxujun1981   发布时间: 2010-10-25

回复 zhangxujun1981


    不要打开/dev/mem
自己做一个kernel driver.
open/mmap时访问的是你这个kernel driver创建的/dev/xxx
pf handler自然建立的vir address --> phy address的映射关系是通过你自己创建的页表,记住页表项的属性是non-cached.

如果还不行,那就说明不是cache的关系.得再想想

作者: snail_314   发布时间: 2010-10-25