qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] Add option to slow down qemu


From: Stefan Weil
Subject: Re: [Qemu-devel] [PATCH] Add option to slow down qemu
Date: Fri, 11 Jan 2013 20:58:43 +0100
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.16) Gecko/20121215 Iceowl/1.0b1 Icedove/3.0.11

Am 11.01.2013 14:40, schrieb Wolfgang Mauerer:
For slow targets and fast hosts, the emulation may be faster
than the actual hardware, which can be undesirable for various
reasons. Add a run-time option to slow down the emulation
by sleeping in the CPU emulation.

Signed-off-by: Wolfgang Mauerer<address@hidden>
---
  cpus.c                |   34 ++++++++++++++++++++++++++++++++++
  include/qemu-common.h |    2 ++
  qemu-options.hx       |   13 +++++++++++++
  vl.c                  |   10 ++++++++++
  4 files changed, 59 insertions(+), 0 deletions(-)

diff --git a/cpus.c b/cpus.c
index 4a7782a..41a9e0c 100644
--- a/cpus.c
+++ b/cpus.c
@@ -106,6 +106,11 @@ static QEMUTimer *icount_warp_timer;
  static int64_t vm_clock_warp_start;
  static int64_t qemu_icount;

+static double slowdown_factor = 0.0;
+#ifndef _WIN32
+static struct timespec slowdown_delay;
+#endif
+

Hi,

slowdown_delay is used in configure_slowdown unconditionally,
so I don't expect that the _WIN32 case will compile.

What about using g_usleep? It avoids the conditional compilation.

Is the comparison of double value "slowdown_factor" with 0.0
time critical, or do all QEMU platforms have a fast FPU?

Setting a boolean value once and testing that value would
be much faster of course.

Cheers,
Stefan W.


  typedef struct TimersState {
      int64_t cpu_ticks_prev;
      int64_t cpu_ticks_offset;
@@ -385,6 +390,21 @@ void configure_icount(const char *option)
                     qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() / 10);
  }

+void configure_slowdown(const char *option)
+{
+    if (!option) {
+        return;
+    }
+
+    slowdown_factor = strtod(option, NULL)/100.0;
+    /* We cannot provide speedups, obviously */
+    if (slowdown_factor<  0) {
+        slowdown_factor *= -1.0;
+    }
+
+    slowdown_delay.tv_sec = 0;
+}
+
  /***********************************************************/
  void hw_error(const char *fmt, ...)
  {
@@ -1092,6 +1112,7 @@ void vm_stop_force_state(RunState state)
  static int tcg_cpu_exec(CPUArchState *env)
  {
      int ret;
+    int64_t ss, delta;
  #ifdef CONFIG_PROFILER
      int64_t ti;
  #endif
@@ -1112,7 +1133,20 @@ static int tcg_cpu_exec(CPUArchState *env)
          env->icount_decr.u16.low = decr;
          env->icount_extra = count;
      }
+    ss = qemu_get_clock_ns(rt_clock);
+
      ret = cpu_exec(env);
+
+    if (slowdown_factor>  0) {
+        delta = qemu_get_clock_ns(rt_clock) - ss;
+        delta *= slowdown_factor;
+#ifdef _WIN32
+        Sleep(delta/1000000l);
+#else
+        slowdown_delay.tv_nsec = delta;
+        nanosleep(&slowdown_delay, NULL);
+#endif
+    }
  #ifdef CONFIG_PROFILER
      qemu_time += profile_getclock() - ti;
  #endif
diff --git a/include/qemu-common.h b/include/qemu-common.h
index ca464bb..652abb9 100644
--- a/include/qemu-common.h
+++ b/include/qemu-common.h
@@ -119,6 +119,8 @@ static inline char *realpath(const char *path, char 
*resolved_path)
  void configure_icount(const char *option);
  extern int use_icount;

+void configure_slowdown(const char *option);
+
  /* FIXME: Remove NEED_CPU_H.  */
  #ifndef NEED_CPU_H

diff --git a/qemu-options.hx b/qemu-options.hx
index 9df0cde..2f6580f 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2665,6 +2665,19 @@ order cores with complex cache hierarchies.  The number 
of instructions
  executed often has little or no correlation with actual performance.
  ETEXI

+DEF("slowdown", HAS_ARG, QEMU_OPTION_slowdown, \
+    "-slowdown s \n" \
+    "                Slow down the CPU emulation by (approximately) s"
+    "                  percent\n", QEMU_ARCH_ALL)
+STEXI
address@hidden -slowdown address@hidden
address@hidden -slowdown
+Slow down the virtual CPU by approximately s percent. This makes it
+possible to align the emulated machine's performance roughly with
+the performance of physical entities, but does not provide identical
+performance profiles since the emulation is not cycle accurate.
+ETEXI
+
  DEF("watchdog", HAS_ARG, QEMU_OPTION_watchdog, \
      "-watchdog i6300esb|ib700\n" \
      "                enable virtual hardware watchdog [default=none]\n",
diff --git a/vl.c b/vl.c
index 79e5122..624551f 100644
--- a/vl.c
+++ b/vl.c
@@ -2524,6 +2524,7 @@ int main(int argc, char **argv, char **envp)
      int i;
      int snapshot, linux_boot;
      const char *icount_option = NULL;
+    const char *slowdown_option = NULL;
      const char *initrd_filename;
      const char *kernel_filename, *kernel_cmdline;
      char boot_devices[33] = "cad"; /* default to HD->floppy->CD-ROM */
@@ -3402,6 +3403,9 @@ int main(int argc, char **argv, char **envp)
              case QEMU_OPTION_icount:
                  icount_option = optarg;
                  break;
+            case QEMU_OPTION_slowdown:
+                slowdown_option = optarg;
+                break;
              case QEMU_OPTION_incoming:
                  incoming = optarg;
                  runstate_set(RUN_STATE_INMIGRATE);
@@ -3765,6 +3769,12 @@ int main(int argc, char **argv, char **envp)
      /* clean up network at qemu process termination */
      atexit(&net_cleanup);

+    if (slowdown_option&&  (kvm_enabled() || xen_enabled())) {
+        fprintf(stderr, "-slowdown is not allowed with kvm or xen\n");
+        exit(1);
+    }
+    configure_slowdown(slowdown_option);
+
      if (net_init_clients()<  0) {
          exit(1);
      }




reply via email to

[Prev in Thread] Current Thread [Next in Thread]