Chinaunix

标题: ioremap之后得到的地址是否可以用memcpy和memset函数 [打印本页]

作者: 527639827    时间: 2010-07-05 08:19
标题: ioremap之后得到的地址是否可以用memcpy和memset函数
用ioremap将设备的寄存器重映射到一个地址上,比如得到地址0xC0000000, 正常来说可以用readl() writel()函数进行读写,
那么是否可以用memcpy()或者memset()进行批量的读写呢?而不是四个字节的读写?
作者: lianhd    时间: 2010-07-05 08:33
回复 1# 527639827

可以
作者: klanet    时间: 2010-07-05 08:50
我觉得不可以
io读写只能是字/半字读写
作者: openspace    时间: 2010-07-05 10:24
LZ可以试一下
我理解的既然映射到内存地址空间了,应该可以这样做
作者: 527639827    时间: 2010-07-05 11:25
经测试是可以的,不过memset的效率并不高啊。跟for循环一样。


我的程序主要是对一大片内存区域写值,随便什么值都行。

一开始我用的是for循环+writel组合,感觉效率低,
就想到用memset写,想不到还是一样的速率,才30MB/s左右的速度。


请教各位大侠一下,有没有办法提高这个写入速度?
作者: openspace    时间: 2010-07-05 16:12
不知道数据是从哪来的
感觉单纯IO的话可能速度就是这样了
如果数据是从用户态来的,可以考虑这方面有没有可以提升的地方
作者: emmoblin    时间: 2010-07-05 20:39
做了ioremap就是把对外设的访问转换成对内存的访问
作者: 527639827    时间: 2010-07-06 09:02
不知道数据是从哪来的
感觉单纯IO的话可能速度就是这样了
如果数据是从用户态来的,可以考虑这方面有没有 ...
openspace 发表于 2010-07-05 16:12



    数据就是随意想的,比如100个循环,可以每次都写i值到4Byte的地方

  单纯IO是啥意思?你是说Linux内核对for的操作也就这么快了?30MB/s的写入速度?

   数据没在用户态产生,直接在内核态写的
作者: 527639827    时间: 2010-07-06 09:08
回复 7# emmoblin


    恩,是这样的,这句话总结得深入浅出啊
作者: garyv    时间: 2010-07-06 15:19
回复 1# 527639827


    这个不一定的,要看具体环境,比如同一个PCI设备的MMIO空间,通过ioremap()映射之后,如果在x86-linux下,是可以当做一片普通的RAM来access的,如果在ppc-linux下,则不能,只能用readl(),writel()
作者: xxw19840406    时间: 2010-07-06 16:36
Linux下的LCD驱动里面是有这样做的
作者: snail_314    时间: 2010-07-06 17:32
回复 8# 527639827


    答案应该是:不能.两者速率应该都是一样的.
为什么?
先来看如果你的address是实实在在的DRAM的话,为什么会快.因为,memset\memcpy等函数比你自己写for循环的优势就是它们能更有效的利用cpu<-->memory之间的cache.
但前提是,只有当address是DRAM时,这些地址才是cacheable的.
也就是说,如果address是来自于ioremap from device address space的话,这些address本身就不应该是cacheable的,因为本来就需要立即将它们写入device.所以,此时memset/memcpy和你for loop一个个写时performance应该一样.
作者: 527639827    时间: 2010-07-07 09:26
回复 12# snail_314


    我现在要做的是快速的写值到一个pci switch的bar代表的地址空间中,写什么值无所谓。主要是测传送的速度。

   现在的做法是ioremap之后,用writel()或者memset()写,但是效率只有31MB/s,比理论的传送效率低了几十倍。

   那么瓶颈就在于CPU处理写值到bar代表的地址空间,怎样才能够快速的写值到这个pci switch的bar空间呢?

   有人说DMA非常快,能够释放CPU,但是那个pci switch不支持DMA啊,所以这条路行不通了
作者: linux初学三月    时间: 2010-07-07 16:14
用memcpy()或者memset()试一下就可以了
作者: 527639827    时间: 2010-07-07 16:44
回复 14# linux初学三月

这两个和循环的速度一样,31MB/s

听说有一种CPU侧的DMA,不知道哪位大侠有相关的资料,给我参考下啊
作者: accessory    时间: 2010-07-08 00:17
回复 15# 527639827

对于PCI, PCIE 总线的设备来说, 我从来没听说过CPU侧的DMA. 都是要设备自己支持DMA才行.

老的ISA的时候,倒是在主板上有几个专门的DMA 控制器.
作者: accessory    时间: 2010-07-08 00:31
回复 13# 527639827

"但是效率只有31MB/s,比理论的传送效率低了几十倍。"
哪里有几十倍? 你用的下面中的哪个PCI?  还是PCI EXPRESS?  PCI OR PCIE 规范版本是几点几的?

133 MB/s (32-bit at 33 MHz)
266 MB/s (32-bit at 66 MHz or 64-bit at 33 MHz)
533 MB/s (64-bit at 66 MHz)

另外, PCI 支持BURST MODE. 不过还要看你的硬件是怎么设计的. 下面是一个关于PCI BURST ON WINDOWS的讨论.

http://www.mombu.com/microsoft/w ... ci-card-749542.html
作者: accessory    时间: 2010-07-08 00:38
OTHER LINKS:
http://www.pcreview.co.uk/forums/thread-2249271.php

http://processors.wiki.ti.com/in ... ghput_on_C64x+_DSPs
作者: 527639827    时间: 2010-07-08 08:32
回复 17# accessory


    哇,老大你真强。

我所说的相差几十倍是这样计算的。

PCIE的速度是2.5Gb/s/lane,也就是320MB/s/lane,我的交换芯片的实测上限速度(厂商测试的)是180MB/s/lane。

而我现在用了4个lane,也就是说速度应该是180MB/s*4=720MB/s,而我现在测试的才31MB/s,所以跟理论的上限值差了几十倍之多。


由于交换芯片本身并不支持DMA,而厂商又不提供当时他们是怎么测试得到180MB/s的实测上限速度,所以我现在很迷惑。

我的测试主要是想交换芯片的bar空间写值,目前的瓶颈就在于我写值的速度太慢,而不是传输速度太慢导致的。而且我现在用死循环的办法写值到bar空间,CPU完全被占用了。

大侠有什么解决的办法或者思路没?
作者: accessory    时间: 2010-07-08 22:44
想要达到那么高的速度又不支持DMA, 那么只能把CPU全占用了,然后不停的写了......囧
作者: snail_314    时间: 2010-07-09 09:38
不光不停的写,还得不让其他设备工作,pci是共享的竞争总线,大家都会分享带宽的
作者: 527639827    时间: 2010-07-09 17:24
回复 21# snail_314


    这个怎么才能实现呢?
作者: snail_314    时间: 2010-07-10 12:50
回复 22# 527639827


    说实话我也没搞过,不过你用firmware来测试吧。不要启linux等os,就像玩一个单片机一样,差不多是那个意思。
作者: qubit6    时间: 2010-07-11 00:20
最好不要用memset之类,而是使用memset_io, memcpy_fromio, memcpy_toio
作者: snail_314    时间: 2010-07-13 15:53
回复 22# 527639827


    你用write-combian来做速度测试吧
作者: 527639827    时间: 2010-07-13 18:36
回复 25# snail_314


    这个咋用呢?
作者: 0vk0    时间: 2010-07-17 10:58
可以用memcpy()或者memset()进行批量的读写




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2