DisplayLink Linux performance metrics
Posted on 03. Dec, 2009 by Bernie Thompson in udlfb
For a USB virtual graphics solution, performance is critical. For the Linux drivers for DisplayLink devices, there are several patches and alternative implementations that are tough to evaluate, compare (and merge) without hard data. It would be great to know what compression ratio we’re getting, how much data is being sent over USB, etc.
So, to enable people to generate that better data, a few lightweight and very low-level benchmarks have been added to udlfb in this patch, which can be grabbed with:
git clone http://git.plugable.com/webdav/udlfb git checkout origin/sysfs-metrics
What has been added is a set of metrics which are exposed through sysfs. After building branch of the driver with “sudo make install; sudo depmod -a” and a reboot, you’ll find these new files on your system:
ls /sys/class/graphics/fb0/metrics_* /sys/class/graphics/fb0/metrics_apis_used /sys/class/graphics/fb0/metrics_bytes_identical /sys/class/graphics/fb0/metrics_bytes_rendered /sys/class/graphics/fb0/metrics_bytes_sent /sys/class/graphics/fb0/metrics_cpu_kcycles_used /sys/class/graphics/fb0/metrics_reset
If you read any of these files, a request will go down to the udlfb driver, and it will return back the matching metric. One file is write-only: metrics_reset. Writing anything to it will set all the others back to zero.
Sysfs is a really nice mechanism — we can now create some more elaborate test scenarios easily from user mode, and get fairly precise data back from kernel mode.
If you have a working setup of X on top of udlfb (I use this method) — or anything that renders to the framebuffer device — you can now get some much better data about what’s happening in udlfb.
As an example, a script called udlfb-perf.sh has been created to run tests and pretty print a simple report. Here’s the output from a test run on my Acer Aspire laptop running Ubuntu 9.04, using gtkperf as scenario to benchmark.
./udlfb-perf.sh fb0 gtkperf -a GtkPerf 0.40 - Starting testing: Thu Dec 3 15:16:12 2009 GtkEntry - time: 0.00 GtkComboBox - time: 3.17 GtkComboBoxEntry - time: 1.93 GtkSpinButton - time: 0.40 GtkProgressBar - time: 0.60 GtkToggleButton - time: 0.45 GtkCheckButton - time: 0.41 GtkRadioButton - time: 0.74 GtkTextView - Add text - time: 1.99 GtkTextView - Scroll - time: 0.86 GtkDrawingArea - Lines - time: 1.89 GtkDrawingArea - Circles - time: 3.13 GtkDrawingArea - Text - time: 3.05 GtkDrawingArea - Pixbufs - time: 0.56 --- Total time: 19.18 Quitting.. model name : Intel(R) Atom(TM) CPU N270 @ 1.60GHz model name : Intel(R) Atom(TM) CPU N270 @ 1.60GHz cpu MHz : 800.000 cpu MHz : 800.000 MemTotal: 2052144 kB Framebuffer Mode: 1920,1080 Rendered bytes: 187064790 (total pixels * Bpp) Identical bytes: 112816894 (skipped via shadow buffer check) sent bytes: 35556944 (compressed usb data, including overhead) K CPU cycles: 4316313 (transpired, may include context switches) % pixels found to be unchanged: 60.00 % Compression of changed pixels : 52.00 % CPU cycles spent per pixel: 23 USB Mbps: 13.56 (theoretical USB 2.0 peak 480)
To run this, you’ll need the udlfb-perf.sh script (shown below, and also in git here)
And you’ll need gtkperf:
sudo apt-get install gtkperf
Run udlfb-perf on your DisplayLink display, passing it the appropriate framebuffer device (e.g. ./udlfb-perf.sh fb0 gtkperf -a)
#!/bin/bash # (C) 2009 Bernie Thompson http://plugable.com/ # License http://www.opensource.org/licenses/mit-license.html if [ $# -eq 0 ] then echo echo "Usage: $0 fbX [test to benchmark] [test parameters ....]" echo "[fbX] must be device visible in /sys/class/graphics directory" echo "and should be the DisplayLink device X is currently using" echo echo "Example: ./udlfb-perf.sh fb0 gtkperf -a" echo exit 1 fi dev=$1 prog=$2 shift 2 echo 1 > /sys/class/graphics/$dev/metrics_reset start=$(date +%s) $prog $@ end=$(date +%s) rendered=`cat /sys/class/graphics/$dev/metrics_bytes_rendered` sent=`cat /sys/class/graphics/$dev/metrics_bytes_sent` identical=`cat /sys/class/graphics/$dev/metrics_bytes_identical` cycles=`cat /sys/class/graphics/$dev/metrics_cpu_kcycles_used` mode=`cat /sys/class/graphics/$dev/virtual_size` bus_compress=`/usr/bin/bc <<EOF scale=2; (($rendered - $identical - $sent) / ($rendered - $identical)) * 100 EOF` unchanged_pct=`/usr/bin/bc <<EOF scale=2; (($identical) / $rendered) * 100 EOF` mbps=`/usr/bin/bc <<EOF scale=2; ($sent) / ($end - $start) * 8 / 1048576 EOF` cycles_per_pix=`/usr/bin/bc <<EOF scale=0; $cycles * 1000 / $rendered EOF` echo /bin/grep "model name" /proc/cpuinfo /bin/grep "MHz" /proc/cpuinfo /bin/grep "MemTotal" /proc/meminfo echo "Framebuffer Mode: $mode" echo echo "Rendered bytes: $rendered (total pixels * Bpp)" echo "Identical bytes: $identical (skipped via shadow buffer check)" echo "sent bytes: $sent (compressed usb data, including overhead)" echo "K CPU cycles: $cycles (transpired, may include context switches)" echo echo "% pixels found to be unchanged: $unchanged_pct %" echo "Compression of changed pixels : $bus_compress %" echo "CPU cycles spent per pixel: $cycles_per_pix" echo "USB Mbps: $mbps (theoretical USB 2.0 peak 480)" echo
It’d be interesting to see results from other systems and/or some suggested benchmarks other than gtkperf (especially a repeatable video playback test). Please feel free to comment with any of that.

Recent Comments