Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Profiling the switching time is very difficult, but the in-kernel latency profiling tools, as well as oprofile (which can profile the kernel itself) will help you there.</p> <p>For benchmarking the interactive application performance, I have written a small tool called latencybench that measures unexpected latency spikes:</p> <pre><code>// Compile with g++ latencybench.cc -o latencybench -lboost_thread-mt // Should also work on MSVC and other platforms supported by Boost. #include &lt;boost/format.hpp&gt; #include &lt;boost/thread/thread.hpp&gt; #include &lt;boost/date_time.hpp&gt; #include &lt;algorithm&gt; #include &lt;cstdlib&gt; #include &lt;csignal&gt; volatile bool m_quit = false; extern "C" void sighandler(int) { m_quit = true; } std::string num(unsigned val) { if (val == 1) return "one occurrence"; return boost::lexical_cast&lt;std::string&gt;(val) + " occurrences"; } int main(int argc, char** argv) { using namespace boost::posix_time; std::signal(SIGINT, sighandler); std::signal(SIGTERM, sighandler); time_duration duration = milliseconds(10); if (argc &gt; 1) { try { if (argc != 2) throw 1; unsigned ms = boost::lexical_cast&lt;unsigned&gt;(argv[1]); if (ms &gt; 1000) throw 2; duration = milliseconds(ms); } catch (...) { std::cerr &lt;&lt; "Usage: " &lt;&lt; argv[0] &lt;&lt; " milliseconds" &lt;&lt; std::endl; return EXIT_FAILURE; } } typedef std::map&lt;long, unsigned&gt; Durations; Durations durations; unsigned samples = 0, wrongsamples = 0; unsigned max = 0; long last = -1; std::cout &lt;&lt; "Measuring actual sleep delays when requesting " &lt;&lt; duration.total_milliseconds() &lt;&lt; " ms: (Ctrl+C when done)" &lt;&lt; std::endl; ptime begin = boost::get_system_time(); while (!m_quit) { ptime start = boost::get_system_time(); boost::this_thread::sleep(start + duration); long actual = (boost::get_system_time() - start).total_milliseconds(); ++samples; unsigned num = ++durations[actual]; if (actual != last) { std::cout &lt;&lt; "\r " &lt;&lt; actual &lt;&lt; " ms " &lt;&lt; std::flush; last = actual; } if (actual != duration.total_milliseconds()) { ++wrongsamples; if (num &gt; max) max = num; std::cout &lt;&lt; "spike at " &lt;&lt; start - begin &lt;&lt; std::endl; last = -1; } } if (samples == 0) return 0; std::cout &lt;&lt; "\rTotal measurement duration: " &lt;&lt; boost::get_system_time() - begin &lt;&lt; "\n"; std::cout &lt;&lt; "Number of samples collected: " &lt;&lt; samples &lt;&lt; "\n"; std::cout &lt;&lt; "Incorrect delay count: " &lt;&lt; wrongsamples &lt;&lt; boost::format(" (%.2f %%)") % (100.0 * wrongsamples / samples) &lt;&lt; "\n\n"; std::cout &lt;&lt; "Histogram of actual delays:\n\n"; unsigned correctsamples = samples - wrongsamples; const unsigned line = 60; double scale = 1.0; char ch = '+'; if (max &gt; line) { scale = double(line) / max; ch = '*'; } double correctscale = 1.0; if (correctsamples &gt; line) correctscale = double(line) / correctsamples; for (Durations::const_iterator it = durations.begin(); it != durations.end(); ++it) { std::string bar; if (it-&gt;first == duration.total_milliseconds()) bar = std::string(correctscale * it-&gt;second, '&gt;'); else bar = std::string(scale * it-&gt;second, ch); std::cout &lt;&lt; boost::format("%5d ms | %s %d") % it-&gt;first % bar % it-&gt;second &lt;&lt; std::endl; } std::cout &lt;&lt; "\n"; std::string indent(30, ' '); std::cout &lt;&lt; indent &lt;&lt; "+-- Legend ----------------------------------\n"; std::cout &lt;&lt; indent &lt;&lt; "| &gt; " &lt;&lt; num(1.0 / correctscale) &lt;&lt; " (of " &lt;&lt; duration.total_milliseconds() &lt;&lt; " ms delay)\n"; if (wrongsamples &gt; 0) std::cout &lt;&lt; indent &lt;&lt; "| " &lt;&lt; ch &lt;&lt; " " &lt;&lt; num(1.0 / scale) &lt;&lt; " (of any other delay)\n"; } </code></pre> <p>Results on Ubuntu 2.6.32-14-generic kernel. While measuring, I was compiling C++ code with four cores and playing a game with OpenGL graphics at the same time (to make it more interesting):</p> <pre><code>Total measurement duration: 00:01:45.191465 Number of samples collected: 10383 Incorrect delay count: 196 (1.89 %) Histogram of actual delays: 10 ms | &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; 10187 11 ms | *************************************************** 70 12 ms | ************************************************************ 82 13 ms | ********* 13 14 ms | ********* 13 15 ms | ** 4 17 ms | *** 5 18 ms | * 2 19 ms | **** 6 20 ms | 1 +-- Legend ---------------------------------- | &gt; 169 occurrences (of 10 ms delay) | * one occurrence (of any other delay) </code></pre> <p>With rt-patched kernels I get much better results, pretty much 10-12 ms only.</p> <p>The legend in the printout appears to be suffering of a rounding error or something (and the source code pasted is not the exact same version). I never really polished this application for a release...</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload