qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] Precise guest instruction count.


From: Laurent Desnogues
Subject: Re: [Qemu-devel] Precise guest instruction count.
Date: Mon, 9 Mar 2009 22:56:32 +0100

On Mon, Mar 9, 2009 at 10:38 AM, Steffen Liebergeld <address@hidden> wrote:
>
> I have difficulties getting to know the number of guest instructions. I tried
> to use the -icount switch, but this leads to timeout errors whenever the guest
> tries to use the network. So I inserted a line into gen_icount_end, which
> ,regardless of the value use_icount, increments qemu_icount by num_insns. I
> assume, that the code of gen_icount_end is appended to all TBs and run
> whenever the TB is run (please correct me if I'm wrong).

That's almost correct:  icount code is inserted at the beginning not appended.
You should not try to play with icount code but create your own set of code
that replicates it.

Something like this:

static inline void gen_icount_start(TCGContext *s, TCGv_ptr cpu_env)
{
    TCGv_i64 count;

    if (!iprofiler.enable_icount)
        return;

    count = tcg_temp_new_i64(s);
    tcg_gen_ld_i64(s, count, cpu_env, offsetof(CPUState, instr_count));
    /* This is a horrid hack to allow fixing up the value later.  */
    iprofiler_tcg.icount_arg = s->gen_opparam_ptr + 1;
    // LD NOTE this may not work!  cf tcg_gen_addi_i64 implementation
    tcg_gen_addi_i64(s, count, count, 0xdeadbeef);
    tcg_gen_st_i64(s, count, cpu_env, offsetof(CPUState, instr_count));
    tcg_temp_free_i64(s, count);
}

static void gen_icount_end(int num_insns)
{
    if (iprofiler.enable_icount) {
        *iprofiler_tcg.icount_arg = (int64_t)num_insns;
    }
}

Note the function names I chose are confusing...

> I have some code in the guest, which does some calculations. I let it do the
> calculations several times in a row, always discarding the results of the
> previous run. I trigger the NOP always before the calculation and Qemu gives
> me the following as values of qemu_icount:
> First run:  835032
> Second run: 837176
> Third run:  837179
> Fourth and subsequent runs: 837180
>
> I guess that the behaviour is caused by chaining of TBs. The execution flow
> jumps directly to the next TB without running the code of gen_icount_end at
> the end of the TB.

gen_icount_end is not at the end of the TB, it only patches code that was
inserted at the beginning of the TB by gen_icount_start.

The variations you see are probably due to timing variations. Even in user
mode you can have slightly different results for code that for instance
prints elapsed time.

HTH,

Laurent




reply via email to

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