+ -
当前位置:首页 → 问答吧 → ioremap之后得到的地址是否可以用memcpy和memset函数

ioremap之后得到的地址是否可以用memcpy和memset函数

时间:2010-07-05

来源:互联网

用ioremap将设备的寄存器重映射到一个地址上,比如得到地址0xC0000000, 正常来说可以用readl() writel()函数进行读写,
那么是否可以用memcpy()或者memset()进行批量的读写呢?而不是四个字节的读写?

作者: 527639827   发布时间: 2010-07-05

回复 527639827

可以

作者: lianhd   发布时间: 2010-07-05

我觉得不可以
io读写只能是字/半字读写

作者: klanet   发布时间: 2010-07-05

LZ可以试一下
我理解的既然映射到内存地址空间了,应该可以这样做

作者: openspace   发布时间: 2010-07-05

经测试是可以的,不过memset的效率并不高啊。跟for循环一样。


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

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


请教各位大侠一下,有没有办法提高这个写入速度?

作者: 527639827   发布时间: 2010-07-05

不知道数据是从哪来的
感觉单纯IO的话可能速度就是这样了
如果数据是从用户态来的,可以考虑这方面有没有可以提升的地方

作者: openspace   发布时间: 2010-07-05

做了ioremap就是把对外设的访问转换成对内存的访问

作者: emmoblin   发布时间: 2010-07-05



QUOTE:
不知道数据是从哪来的
感觉单纯IO的话可能速度就是这样了
如果数据是从用户态来的,可以考虑这方面有没有 ...
openspace 发表于 2010-07-05 16:12




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

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

   数据没在用户态产生,直接在内核态写的

作者: 527639827   发布时间: 2010-07-06

回复 emmoblin


    恩,是这样的,这句话总结得深入浅出啊

作者: 527639827   发布时间: 2010-07-06

回复 527639827


    这个不一定的,要看具体环境,比如同一个PCI设备的MMIO空间,通过ioremap()映射之后,如果在x86-linux下,是可以当做一片普通的RAM来access的,如果在ppc-linux下,则不能,只能用readl(),writel()

作者: garyv   发布时间: 2010-07-06

Linux下的LCD驱动里面是有这样做的

作者: xxw19840406   发布时间: 2010-07-06

回复 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应该一样.

作者: snail_314   发布时间: 2010-07-06

回复 snail_314


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

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

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

   有人说DMA非常快,能够释放CPU,但是那个pci switch不支持DMA啊,所以这条路行不通了

作者: 527639827   发布时间: 2010-07-07

用memcpy()或者memset()试一下就可以了

作者: linux初学三月   发布时间: 2010-07-07

回复 linux初学三月

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

听说有一种CPU侧的DMA,不知道哪位大侠有相关的资料,给我参考下啊

作者: 527639827   发布时间: 2010-07-07

回复 527639827

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

老的ISA的时候,倒是在主板上有几个专门的DMA 控制器.

作者: accessory   发布时间: 2010-07-08

回复 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

回复 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完全被占用了。

大侠有什么解决的办法或者思路没?

作者: 527639827   发布时间: 2010-07-08

想要达到那么高的速度又不支持DMA, 那么只能把CPU全占用了,然后不停的写了......囧

作者: accessory   发布时间: 2010-07-08

不光不停的写,还得不让其他设备工作,pci是共享的竞争总线,大家都会分享带宽的

作者: snail_314   发布时间: 2010-07-09

回复 snail_314


    这个怎么才能实现呢?

作者: 527639827   发布时间: 2010-07-09

回复 527639827


    说实话我也没搞过,不过你用firmware来测试吧。不要启linux等os,就像玩一个单片机一样,差不多是那个意思。

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

最好不要用memset之类,而是使用memset_io, memcpy_fromio, memcpy_toio

作者: qubit6   发布时间: 2010-07-11

回复 527639827


    你用write-combian来做速度测试吧

作者: snail_314   发布时间: 2010-07-13

回复 snail_314


    这个咋用呢?

作者: 527639827   发布时间: 2010-07-13

可以用memcpy()或者memset()进行批量的读写

作者: 0vk0   发布时间: 2010-07-17

热门下载

更多