mailme
驱动老牛
驱动老牛
  • 注册日期2001-05-21
  • 最后登录2010-02-25
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望3点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
阅读:1075回复:1

请教各位大侠:如何提高PCI板卡的数据吞吐率??

楼主#
更多 发布于:2002-03-16 11:44
我的WDM驱动是这样的:

其实该PCI板对驱动的功能要求很简单,主要就是先写再读128位(16字节)数据。板子是32位(4字节)映射MEMORY,也就是每次读写
均需循环4次。我的驱动采用了以下两种方法:

   1、因为板卡没有提供中断,我就用DeviceIoControl(同步)读写数据,用缓冲区方式进行数据传递。驱动的DeviceIoControlHandler收到IRP,经过一系列的准备操作后,直接就用WRITE_REGISTER_ULONG先向板子上的32位映射MEMORY写128位数据,等检测到板子将128位数据处理完后(板子处理的时间很短,且不记做驱动占用的时间),再用READ_REGISTER_ULONG从板子中读出128位数据返回给用户态,完成本次IRP操作。然后用户态继续发送下一个DeviceIoControl,就这样连续处理每个128位数据,直到将全部数据处理完。  

    问题是,我用一块声卡作测试连续读写1M字节数据,发现速度奇慢,简直不堪忍受(数秒钟)。我想PCI的带宽有100多,瓶颈肯定在驱动这里。老板要求整个板子的处理速度不能低于1M字节/秒,到驱动这里读写1M字节数据的时间不能多于300毫秒。


    2、我觉得是用户态和内核态交互的时间花的太多了,有1M/16=64K次哪。于是我将驱动做了一些改动,还是用同步DeviceIoControl,但是采用直接方式(DIRECT_IN)访问用户态数据,直接就在DeviceIoControlHandler中向板子的MEMORY写数据,再将每次读MEMORY的结果保存到自建的内核态缓冲区,等到数据全部处理完后,完成本次IRP。再发一个DeviceIoControl(DIRECT_OUT方式),将缓冲区里的数据读出来。这样一改,只用两次DeviceIoControl就完成了全部数据处理,驱动花的时间大大减少,只有200毫秒左右。  

    但是又产生了新的问题:板子在进行128位数据处理时要将前一个处理完的128位数据和后面的待处理128位数据进行一个“预处理算法”,而且有几种不同的预处理方式由用户态选择。在第一种方法中这些“预处理算法”可以交给用户态上层程序完成,在第二种方法中则只能交给驱动程序内部进行“预处理算法”了,但这会使驱动显得非常复杂,且极易出错。


    所以,我想请教各位大侠,如果驱动采用第一种方法(每个IRP_MJ_DEVICE_CONTROL处理128位数据),能否有什么方法大幅提高数据吞吐率?用异步DeviceIoControl??还是用ReadFile、WriteFile???

        本人初学驱动开发,希望各位大侠能帮帮我,先谢谢了!!


[编辑 -  3/16/02 作者: mailme]
早起早睡 精神百倍
mailme
驱动老牛
驱动老牛
  • 注册日期2001-05-21
  • 最后登录2010-02-25
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望3点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-03-17 10:22
可能我的表述太复杂了,各位大虾看的太累,我将我的驱动作一个摘要:

1.总共写和读1M字节数据
2.用缓冲区方式,访问pci板卡的32bit MEMORY映射空间
3.用同步DeviceIoControl,每个IRP_MJ_DEVICE_CONTROL先写再读128bit数据

采用上面的方法读写1M字节数据耗时很长(N秒),请问如何改动上面的各项可以达到大幅提高数据吞吐率的要求(几百毫秒)?老板催的急,星期天还加班:(,希望各位帮帮我!
早起早睡 精神百倍
游客

返回顶部