Linux中的DMA memcpy操作

时间:2014-08-27 07:37:48

标签: linux dma

我想使用dmaengine.c文件(linux / drivers / dma)中的dma_async_memcpy_buf_to_buf函数进行dma。为此,我在dmatest.c文件(linux / drivers / dma)中添加了一个函数,如下所示:

void foo ()
{
    int index = 0;
    dma_cookie_t cookie;
    size_t len = 0x20000;

    ktime_t start, end, end1, end2, end3;
    s64 actual_time;    

    u16* dest;
    u16* src;

    dest = kmalloc(len, GFP_KERNEL);
    src = kmalloc(len, GFP_KERNEL);

    for (index = 0; index < len/2; index++)
    {
        dest[index] = 0xAA55;
        src[index] = 0xDEAD;
    }

    start = ktime_get();
    cookie = dma_async_memcpy_buf_to_buf(chan, dest, src, len);

    while (dma_async_is_tx_complete(chan, cookie, NULL, NULL) == DMA_IN_PROGRESS)
    {
       dma_sync_wait(chan, cookie);
    }
    end = ktime_get();
    actual_time = ktime_to_ns(ktime_sub(end, start));
    printk("Time taken for function() execution     dma: %lld\n",(long long)actual_time);   

    memset(dest, 0 , len);

    start = ktime_get();
    memcpy(dest, src, len);

    end = ktime_get();
    actual_time = ktime_to_ns(ktime_sub(end, start));
    printk("Time taken for function() execution non-dma: %lld\n",(long long)actual_time);
}

DMA存在一些问题:

  1. 有趣的是,memcpy函数执行时间小于dma_async_memcpy_buf_to_buf函数。也许,它与ktime_get()函数问题有关。

  2. 我的foo函数方法执行DMA操作是正确还是不正确?我不确定这一点。

  3. 如何根据cpu使用情况衡量memcpy和dma_async_memcpy_buf_to_buf函数的滴答计数

  4. 最后,在应用程序级别是否可以进行DMA操作?到目前为止,我在内核级别使用,如上所示(dmatest.c是插入内核模块)

1 个答案:

答案 0 :(得分:9)

您的问题中存在多个问题,这使得您很难准确回答您的质疑:

  1. 是的,您的常规DMA操作调用算法是正确的。

  2. 使用普通memcpy和DMA操作复制内存的根本区别在于没有获得直接的性能提升,但是(a)由于在使用DMA操作时维持CPU缓存/预取器状态而导致性能提升(当使用普通的旧memcpy,在CPU本身上执行时,可能会出现乱码),以及(b)真正的后台操作,使CPU可用于执行其他操作。

  3. 鉴于(a),对低于CPU缓存大小的任何东西使用DMA操作都是毫无意义的,即几十兆字节。通常,它是为了快速脱离CPU流处理而完成的,即移动无论如何由外部设备生成/消费的数据,例如快速网卡,视频流/捕获/编码硬件等。

  4. 根据挂钟经过的时间比较异步和同步操作是错误的。可能有数百个线程/进程正在运行,并且没有人保证您将在下一个时间点进行安排,而不是在数千个时间点之后进行安排。

  5. 使用ktime_get进行基准测试是错误的 - 这是相当不精确的,特别是对于这么短的工作。事实上,分析内核代码是一项非常困难和复杂的任务,这远远超出了这个问题的范围。这里的一个快速建议就是完全避免这样的微观基准,并提出更大更完整的工作 - 类似于你最终想要实现的目标。

  6. 测量现代CPU的“滴答”也没有意义,尽管您可以使用CPU供应商特定的工具,例如Intel's VTune

  7. 在应用程序级别上使用DMA复制操作是毫无意义的 - 至少我不能从头脑中找到一个可行的方案,当它值得麻烦时。它本身并不快,而且,更重要的是,我严重怀疑应用程序性能的瓶颈是内存复制。对于这种情况,您通常应该比常规内存复制更快地执行更快的所有操作,并且我无法在应用程序级别上考虑比memcpy更快的任何内容。如果我们谈论与其他一些非CPU处理设备的通信,那么它会自动而不是应用程序级别。

  8. 通常,存储器复制性能通常受存储器速度的限制,即时钟频率和时序。只是因为在CPU上执行的memcpy足够快,因为CPU通常可以比内存快3到5倍-10倍的时钟频率,所以你不会在常规memcpy中获得任何奇迹提升。