This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

DM365/368 CPU load during USB write to external flash drive

I am evaluating the performance of the DM365 using the DM365 EVM (Digital Spectrum) Board. I am seeing disruption in the video quality when I encode 720P60 video while writing the encoded data to a USB flash drive. I would like to know if this is the expected performance of the device or if something can be done to optimize my code.

Here is my test setup:

 

-          Using 4.0.2 DVSDK

-          Semi-Custom Linux Kernel (2.6.32.17-davinci1 #7 PREEMPT) – modified to add support for wireless

which is NOT used in this test) – see attached .config file for details

-          Add-on Wireless compat_wireless driver (for wireless usb dongle – again NOT used in this test)

-          Wired NFS mounted root file system on a modest Linux Host system.

-          Wired Connection to a separate Linux host (same subnet) – for transfer rate testing

-          USB 2.0 directly to a USB Flash Drive (PNY Attache (4G))

  • Flash drive (/dev/sda1) automatically

-          Component 720P60 Video Input.

-          Using the following demo ‘encode’ command line (a small 5 minute clip):

 

./encode -v /media/sda1/tmp.mpeg4 -b 8000000 -I 3 -y 3 –w –t 300

 

I just ran this test again on the DM365 – with JUST writing to USB Flash, not reading back out:

-          47% Loading (actually that is pretty good – it was >55% in previous tests

-          29.0 frames per second

-          7.26Mbit video bitrate

 

Compared to DM368 (same setup otherwise):

-          43% Loading

-          28.8 Frames Per Second (it looks like it dropped more than a few frames)

-          7.95Mbit

 

  • Lynne,

    Try changing the writer thread to fflush and fsync periodically and see if that helps.  It won't reduce the CPU load, but it will force the data to be written to the drive more frequently.

    Without this, the kernel's write buffer will need to fill up (or a certain amount of time must pass) before it actually writes the data to the device.  In this case, the writer thread will block while writing, preventing the video encoder thread from having an available buffer from the fifo, causing it to block, etc, all the way up to the capture thread and then it will drop frames.

    I've also noticed that the choice of filesystem can make a noticeable difference here.  FAT did not work so well for me, versus, say, ext2.  I'm using 2.6.37, so YMMV.

    Mark

  • Thanks Mark,

     

    Implementing this made it MUCH worse – if you can believe that! (fsync and fflush – together, alone, staggered calling…etc )

    The CPU is actually more, and frame rate/ video bitrate are less –  

     

       from 53% Loading, 7.6Mbit, 27fps

       to       59% Loading, 6.4Mbit, 25fps

  • Lynne,

    How frequently are you calling fflush / fsync?  Hopefully not every frame, that would be far too frequently.

    Mark

  • I started @ every 15 frames, moved it up to 90 frames, then up to 150, and then up to 300 frames...

     

    I tried both, and it was slightly better with fflush than both or fsync….

  • I'm out of ideas, then.  You'll have to experiment and figure out where the bottleneck is.

    Have you timed copying a file to the USB stick without the encoding process?  How is the drive formatted / partitioned?

  • Interesting, very interesting question. It is a 4Gig 1 FAT partition. I tested 8Gig drive (newer too) 1 FAT partition: ~3 seconds (avg) ->5.6MB

    That is a lot better write time – but that is blocking write I/O 100% dedicated to writing.

    But, this query brings up an interesting experiment. 

    A raw copy from ramdisk /media/ram/tmp.264 to usb stick /media/sda1/tmp.264 (~16MB file) Takes 6.45 seconds which translates into ~2.6MB/second write speed.

    Further, a raw copy from ramdisk /media/ram/tmp.264 to a modest mmc stick (x4 – I’ve been testing that this morning) /media/mmcblk0p1/tmp.264 (~16MB file) takes 3.45 seconds which translates into ~4.8MB/second write speed (which sorta makes sense (x4 = 4MBs)…

    It looks like the encoding processing and writing are conflicting cause the writer thread to block? I am not sure?

    On the ‘encode’ demo app, the Writer thread is a separate thread that is essentially the asynchronous I/O for the encode data flow.

     The only thing left I can think of would be to set the priority of the writer thread ‘lower’ than the rest of the threads in the encode process. I’ll get back to you if this improves anything.

     

    best,

    Lynne

     

  • Hi Lynne,

    A couple of thoughts:

    To make the operating system flush its buffers to the SD card more often, we've found it useful to mess with the dirty_expire_centisecs variable in the sysfs of Linux.  This value represents how long the OS waits before it automatically flushes its write-out contents to the SD card.  The default is usually 3000, which means it will wait thirty seconds or until its buffers are full.  This default made us lose a lot of data if we shut down our system without flushing buffers and avoids the major delays that occur when you use fflush or fsync (which likewise didn't work well for us). 

    Also, be aware that different SD cards have different write-speed capabilities.  SD cards have a class rating which supposedly represents the write-speed in MB/sec (so a class 2 can purportedly do 2 MB/sec).  If the class rating is not stated, it's probably a class 2.  I would make sure to use a high rating (6 or more).  Also, the SanDisk Mobile Ultra SD cards tend to work better than others from my experience.  You might do some experiments to see if the SD card itself is the bottleneck.  Good luck,

    Neil

  • Hi Neil,

    Lynne was asking the questions for me. But, I figured that I would jump in and explain further.

            (btw, the setting is /proc/sys/vm/dirty_expires_centisecs)

    Setup:

    • dm365 -evm nfs mounted
    • command line: encode -v /media/xxx -I 4 -y 3 -b 8000000 -w -t 300 (5 minute test)

    Equipment:

    1. Sandisk Extreme Pro
    2. Sandisk Extreme
    3. an almost new USB Flash (relatively fast) - I am getting some

    Default settings (with Camera Input - no display option @ 720p):

    I tried dirty_expires_centisecs @ 3000 (default), 300, and 30

    @ 3000, it averages ~47-50%

    @ 300, it averages ~50-52%

    @30, it averages ~52-54%

    It just doesn't make sense!

    Tom