qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v1] test-coroutine: test cost introduced by coroutine
@ 2014-08-13 10:08 Ming Lei
  2014-08-13 14:27 ` Benoît Canet
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Ming Lei @ 2014-08-13 10:08 UTC (permalink / raw)
  To: Peter Maydell, qemu-devel, Kevin Wolf
  Cc: Paolo Bonzini, Ming Lei, Gabriel Kerneis, Stefan Hajnoczi,
	Charlie Shepherd

This test runs dummy function with coroutine by using
two enter and one yield since which is a common usage.

So we can see the cost introduced by corouting for running
one function, for example:

	Run operation 20000000 iterations 4.841071 s, 4131K operations/s
	242ns per coroutine

Signed-off-by: Ming Lei <ming.lei@canonical.com>
---
 tests/test-coroutine.c |   30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/tests/test-coroutine.c b/tests/test-coroutine.c
index 6e634f4..e22fae1 100644
--- a/tests/test-coroutine.c
+++ b/tests/test-coroutine.c
@@ -311,6 +311,35 @@ static void perf_baseline(void)
         maxcycles, duration);
 }
 
+static __attribute__((noinline)) void perf_cost_func(void *opaque)
+{
+    qemu_coroutine_yield();
+}
+
+static void perf_cost(void)
+{
+    const unsigned long maxcycles = 40000000;
+    unsigned long i = 0;
+    double duration;
+    unsigned long ops;
+    Coroutine *co;
+
+    g_test_timer_start();
+    while (i++ < maxcycles) {
+        co = qemu_coroutine_create(perf_cost_func);
+        qemu_coroutine_enter(co, &i);
+        qemu_coroutine_enter(co, NULL);
+    }
+    duration = g_test_timer_elapsed();
+    ops = (long)(maxcycles / (duration * 1000));
+
+    g_test_message("Run operation %lu iterations %f s, %luK operations/s, "
+                   "%luns per coroutine",
+                   maxcycles,
+                   duration, ops,
+                   (unsigned long)(1000000000 * duration) / maxcycles);
+}
+
 int main(int argc, char **argv)
 {
     g_test_init(&argc, &argv, NULL);
@@ -325,6 +354,7 @@ int main(int argc, char **argv)
         g_test_add_func("/perf/nesting", perf_nesting);
         g_test_add_func("/perf/yield", perf_yield);
         g_test_add_func("/perf/function-call", perf_baseline);
+        g_test_add_func("/perf/cost", perf_cost);
     }
     return g_test_run();
 }
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [Qemu-devel] [PATCH v1] test-coroutine: test cost introduced by coroutine
  2014-08-13 10:08 [Qemu-devel] [PATCH v1] test-coroutine: test cost introduced by coroutine Ming Lei
@ 2014-08-13 14:27 ` Benoît Canet
  2014-08-13 14:31   ` Gabriel Kerneis
  2014-08-14  0:41   ` Ming Lei
  2014-08-19 13:57 ` Ming Lei
  2014-08-19 14:13 ` Kevin Wolf
  2 siblings, 2 replies; 6+ messages in thread
From: Benoît Canet @ 2014-08-13 14:27 UTC (permalink / raw)
  To: Ming Lei
  Cc: Kevin Wolf, Peter Maydell, qemu-devel, Charlie Shepherd,
	Stefan Hajnoczi, Paolo Bonzini, Gabriel Kerneis

The Wednesday 13 Aug 2014 à 18:08:47 (+0800), Ming Lei wrote :
> This test runs dummy function with coroutine by using
> two enter and one yield since which is a common usage.
> 
> So we can see the cost introduced by corouting for running
> one function, for example:
> 
> 	Run operation 20000000 iterations 4.841071 s, 4131K operations/s
> 	242ns per coroutine
> 
> Signed-off-by: Ming Lei <ming.lei@canonical.com>
> ---
>  tests/test-coroutine.c |   30 ++++++++++++++++++++++++++++++
>  1 file changed, 30 insertions(+)
> 
> diff --git a/tests/test-coroutine.c b/tests/test-coroutine.c
> index 6e634f4..e22fae1 100644
> --- a/tests/test-coroutine.c
> +++ b/tests/test-coroutine.c
> @@ -311,6 +311,35 @@ static void perf_baseline(void)
>          maxcycles, duration);
>  }
>  
> +static __attribute__((noinline)) void perf_cost_func(void *opaque)
> +{
> +    qemu_coroutine_yield();
> +}
> +
> +static void perf_cost(void)
> +{
> +    const unsigned long maxcycles = 40000000;
> +    unsigned long i = 0;
> +    double duration;
> +    unsigned long ops;
> +    Coroutine *co;
> +
> +    g_test_timer_start();
> +    while (i++ < maxcycles) {
> +        co = qemu_coroutine_create(perf_cost_func);

I am not sure qemu_coroutine_create is systematically used.
I rather believe the code try to reuse existing coroutine.

> +        qemu_coroutine_enter(co, &i);
> +        qemu_coroutine_enter(co, NULL);
> +    }
> +    duration = g_test_timer_elapsed();
> +    ops = (long)(maxcycles / (duration * 1000));
> +
> +    g_test_message("Run operation %lu iterations %f s, %luK operations/s, "
> +                   "%luns per coroutine",
> +                   maxcycles,
> +                   duration, ops,
> +                   (unsigned long)(1000000000 * duration) / maxcycles);
> +}
> +
>  int main(int argc, char **argv)
>  {
>      g_test_init(&argc, &argv, NULL);
> @@ -325,6 +354,7 @@ int main(int argc, char **argv)
>          g_test_add_func("/perf/nesting", perf_nesting);
>          g_test_add_func("/perf/yield", perf_yield);
>          g_test_add_func("/perf/function-call", perf_baseline);
> +        g_test_add_func("/perf/cost", perf_cost);
>      }
>      return g_test_run();
>  }
> -- 
> 1.7.9.5
> 
> 

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Qemu-devel] [PATCH v1] test-coroutine: test cost introduced by coroutine
  2014-08-13 14:27 ` Benoît Canet
@ 2014-08-13 14:31   ` Gabriel Kerneis
  2014-08-14  0:41   ` Ming Lei
  1 sibling, 0 replies; 6+ messages in thread
From: Gabriel Kerneis @ 2014-08-13 14:31 UTC (permalink / raw)
  To: Benoît Canet, Ming Lei
  Cc: Kevin Wolf, Peter Maydell, qemu-devel, Charlie Shepherd,
	Stefan Hajnoczi, Paolo Bonzini



On 13 août 2014 16:27:29 CEST, "Benoît Canet" <benoit.canet@irqsave.net> wrote:
> The Wednesday 13 Aug 2014 à 18:08:47 (+0800), Ming Lei wrote :
> > This test runs dummy function with coroutine by using
> > two enter and one yield since which is a common usage.
> > 
> > So we can see the cost introduced by corouting for running
> > one function, for example:
> > 
> > 	Run operation 20000000 iterations 4.841071 s, 4131K operations/s
> > 	242ns per coroutine
> > 
> > Signed-off-by: Ming Lei <ming.lei@canonical.com>
> > ---
> >  tests/test-coroutine.c |   30 ++++++++++++++++++++++++++++++
> >  1 file changed, 30 insertions(+)
> > 
> > diff --git a/tests/test-coroutine.c b/tests/test-coroutine.c
> > index 6e634f4..e22fae1 100644
> > --- a/tests/test-coroutine.c
> > +++ b/tests/test-coroutine.c
> > @@ -311,6 +311,35 @@ static void perf_baseline(void)
> >          maxcycles, duration);
> >  }
> >  
> > +static __attribute__((noinline)) void perf_cost_func(void *opaque)
> > +{
> > +    qemu_coroutine_yield();
> > +}
> > +
> > +static void perf_cost(void)
> > +{
> > +    const unsigned long maxcycles = 40000000;
> > +    unsigned long i = 0;
> > +    double duration;
> > +    unsigned long ops;
> > +    Coroutine *co;
> > +
> > +    g_test_timer_start();
> > +    while (i++ < maxcycles) {
> > +        co = qemu_coroutine_create(perf_cost_func);
> 
> I am not sure qemu_coroutine_create is systematically used.
> I rather believe the code try to reuse existing coroutine.

Isn't it what the coroutine pool is for? Is there really code duplicating it manually? 


> 
> > +        qemu_coroutine_enter(co, &i);
> > +        qemu_coroutine_enter(co, NULL);
> > +    }
> > +    duration = g_test_timer_elapsed();
> > +    ops = (long)(maxcycles / (duration * 1000));
> > +
> > +    g_test_message("Run operation %lu iterations %f s, %luK
> operations/s, "
> > +                   "%luns per coroutine",
> > +                   maxcycles,
> > +                   duration, ops,
> > +                   (unsigned long)(1000000000 * duration) /
> maxcycles);
> > +}
> > +
> >  int main(int argc, char **argv)
> >  {
> >      g_test_init(&argc, &argv, NULL);
> > @@ -325,6 +354,7 @@ int main(int argc, char **argv)
> >          g_test_add_func("/perf/nesting", perf_nesting);
> >          g_test_add_func("/perf/yield", perf_yield);
> >          g_test_add_func("/perf/function-call", perf_baseline);
> > +        g_test_add_func("/perf/cost", perf_cost);
> >      }
> >      return g_test_run();
> >  }
> > -- 
> > 1.7.9.5
> > 
> > 

-- 
Gabriel

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Qemu-devel] [PATCH v1] test-coroutine: test cost introduced by coroutine
  2014-08-13 14:27 ` Benoît Canet
  2014-08-13 14:31   ` Gabriel Kerneis
@ 2014-08-14  0:41   ` Ming Lei
  1 sibling, 0 replies; 6+ messages in thread
From: Ming Lei @ 2014-08-14  0:41 UTC (permalink / raw)
  To: Benoît Canet
  Cc: Kevin Wolf, Peter Maydell, qemu-devel, Charlie Shepherd,
	Stefan Hajnoczi, Paolo Bonzini, Gabriel Kerneis

On Wed, Aug 13, 2014 at 10:27 PM, Benoît Canet <benoit.canet@irqsave.net> wrote:
> The Wednesday 13 Aug 2014 à 18:08:47 (+0800), Ming Lei wrote :
>> This test runs dummy function with coroutine by using
>> two enter and one yield since which is a common usage.
>>
>> So we can see the cost introduced by corouting for running
>> one function, for example:
>>
>>       Run operation 20000000 iterations 4.841071 s, 4131K operations/s
>>       242ns per coroutine
>>
>> Signed-off-by: Ming Lei <ming.lei@canonical.com>
>> ---
>>  tests/test-coroutine.c |   30 ++++++++++++++++++++++++++++++
>>  1 file changed, 30 insertions(+)
>>
>> diff --git a/tests/test-coroutine.c b/tests/test-coroutine.c
>> index 6e634f4..e22fae1 100644
>> --- a/tests/test-coroutine.c
>> +++ b/tests/test-coroutine.c
>> @@ -311,6 +311,35 @@ static void perf_baseline(void)
>>          maxcycles, duration);
>>  }
>>
>> +static __attribute__((noinline)) void perf_cost_func(void *opaque)
>> +{
>> +    qemu_coroutine_yield();
>> +}
>> +
>> +static void perf_cost(void)
>> +{
>> +    const unsigned long maxcycles = 40000000;
>> +    unsigned long i = 0;
>> +    double duration;
>> +    unsigned long ops;
>> +    Coroutine *co;
>> +
>> +    g_test_timer_start();
>> +    while (i++ < maxcycles) {
>> +        co = qemu_coroutine_create(perf_cost_func);
>
> I am not sure qemu_coroutine_create is systematically used.
> I rather believe the code try to reuse existing coroutine.

In block layer, it is a common usage, please see bdrv_co_aio_rw_vector(),
and most of times the allocation hits on the pool, as mentioned by
Gabriel Kerneis().  In this test, it should always be from the pool.

Ming


>
>> +        qemu_coroutine_enter(co, &i);
>> +        qemu_coroutine_enter(co, NULL);
>> +    }
>> +    duration = g_test_timer_elapsed();
>> +    ops = (long)(maxcycles / (duration * 1000));
>> +
>> +    g_test_message("Run operation %lu iterations %f s, %luK operations/s, "
>> +                   "%luns per coroutine",
>> +                   maxcycles,
>> +                   duration, ops,
>> +                   (unsigned long)(1000000000 * duration) / maxcycles);
>> +}
>> +
>>  int main(int argc, char **argv)
>>  {
>>      g_test_init(&argc, &argv, NULL);
>> @@ -325,6 +354,7 @@ int main(int argc, char **argv)
>>          g_test_add_func("/perf/nesting", perf_nesting);
>>          g_test_add_func("/perf/yield", perf_yield);
>>          g_test_add_func("/perf/function-call", perf_baseline);
>> +        g_test_add_func("/perf/cost", perf_cost);
>>      }
>>      return g_test_run();
>>  }
>> --
>> 1.7.9.5
>>
>>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Qemu-devel] [PATCH v1] test-coroutine: test cost introduced by coroutine
  2014-08-13 10:08 [Qemu-devel] [PATCH v1] test-coroutine: test cost introduced by coroutine Ming Lei
  2014-08-13 14:27 ` Benoît Canet
@ 2014-08-19 13:57 ` Ming Lei
  2014-08-19 14:13 ` Kevin Wolf
  2 siblings, 0 replies; 6+ messages in thread
From: Ming Lei @ 2014-08-19 13:57 UTC (permalink / raw)
  To: Peter Maydell, qemu-devel, Kevin Wolf
  Cc: Paolo Bonzini, Ming Lei, Gabriel Kerneis, Stefan Hajnoczi,
	Charlie Shepherd

Hi Guys,

On Wed, Aug 13, 2014 at 6:08 PM, Ming Lei <ming.lei@canonical.com> wrote:
> This test runs dummy function with coroutine by using
> two enter and one yield since which is a common usage.
>
> So we can see the cost introduced by corouting for running
> one function, for example:
>
>         Run operation 20000000 iterations 4.841071 s, 4131K operations/s
>         242ns per coroutine
>
> Signed-off-by: Ming Lei <ming.lei@canonical.com>

Ping...

Thanks,

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Qemu-devel] [PATCH v1] test-coroutine: test cost introduced by coroutine
  2014-08-13 10:08 [Qemu-devel] [PATCH v1] test-coroutine: test cost introduced by coroutine Ming Lei
  2014-08-13 14:27 ` Benoît Canet
  2014-08-19 13:57 ` Ming Lei
@ 2014-08-19 14:13 ` Kevin Wolf
  2 siblings, 0 replies; 6+ messages in thread
From: Kevin Wolf @ 2014-08-19 14:13 UTC (permalink / raw)
  To: Ming Lei
  Cc: Peter Maydell, qemu-devel, Charlie Shepherd, Stefan Hajnoczi,
	Paolo Bonzini, Gabriel Kerneis

Am 13.08.2014 um 12:08 hat Ming Lei geschrieben:
> This test runs dummy function with coroutine by using
> two enter and one yield since which is a common usage.
> 
> So we can see the cost introduced by corouting for running
> one function, for example:
> 
> 	Run operation 20000000 iterations 4.841071 s, 4131K operations/s
> 	242ns per coroutine
> 
> Signed-off-by: Ming Lei <ming.lei@canonical.com>

Thanks, applied to the block branch.

Kevin

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2014-08-19 14:13 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-08-13 10:08 [Qemu-devel] [PATCH v1] test-coroutine: test cost introduced by coroutine Ming Lei
2014-08-13 14:27 ` Benoît Canet
2014-08-13 14:31   ` Gabriel Kerneis
2014-08-14  0:41   ` Ming Lei
2014-08-19 13:57 ` Ming Lei
2014-08-19 14:13 ` Kevin Wolf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).