From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LgnSh-0006r9-1Q for qemu-devel@nongnu.org; Mon, 09 Mar 2009 17:56:39 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LgnSf-0006qB-N8 for qemu-devel@nongnu.org; Mon, 09 Mar 2009 17:56:38 -0400 Received: from [199.232.76.173] (port=50694 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LgnSf-0006q0-In for qemu-devel@nongnu.org; Mon, 09 Mar 2009 17:56:37 -0400 Received: from mail-bw0-f171.google.com ([209.85.218.171]:37954) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1LgnSe-0002sQ-FG for qemu-devel@nongnu.org; Mon, 09 Mar 2009 17:56:36 -0400 Received: by bwz19 with SMTP id 19so1284629bwz.34 for ; Mon, 09 Mar 2009 14:56:33 -0700 (PDT) MIME-Version: 1.0 In-Reply-To: References: Date: Mon, 9 Mar 2009 22:56:32 +0100 Message-ID: <761ea48b0903091456r319a017dlda891b6eca800520@mail.gmail.com> Subject: Re: [Qemu-devel] Precise guest instruction count. From: Laurent Desnogues Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org On Mon, Mar 9, 2009 at 10:38 AM, Steffen Liebergeld 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