Skip to content


Subversion checkout URL

You can clone with
Download ZIP
a Pin tool for collecting microarchitecture-independent workload characteristics
C++ C
Branch: master
Failed to load latest commit information.
LICENSE copied v0.3 in trunk, prepped v0.3 release tarball
Makefile Rename memreusedist to memstackdist.
README update list of contributors with Maxime Chéramy
RELEASE_NOTES bump version to MICA v0.40, and release it
index.html bump version to MICA v0.40, and release it
itypes_default.spec copied v0.3 in trunk, prepped v0.3 release tarball
mica.conf.example append_pid config entry added
mica.cpp Rename memreusedist to memstackdist.
mica.h append_pid config entry added
mica_all.cpp Rename memreusedist to memstackdist.
mica_all.h copied v0.3 in trunk, prepped v0.3 release tarball
mica_ilp.cpp append_pid config entry added
mica_ilp.h copied v0.3 in trunk, prepped v0.3 release tarball
mica_init.cpp Rename memreusedist to memstackdist.
mica_init.h Rename memreusedist to memstackdist.
mica_itypes.cpp append_pid config entry added
mica_itypes.h copied v0.3 in trunk, prepped v0.3 release tarball
mica_memfootprint.cpp Code refactoring memfootprint.
mica_memfootprint.h MICA v0.2 (Dec. 3rd 2007):
mica_memstackdist.cpp Rename memreusedist to memstackdist.
mica_memstackdist.h Rename memreusedist to memstackdist.
mica_ppm.cpp append_pid config entry added
mica_ppm.h MICA v0.2 (Dec. 3rd 2007):
mica_reg.cpp append_pid config entry added
mica_reg.h MICA v0.2 (Dec. 3rd 2007):
mica_stride.cpp append_pid config entry added
mica_stride.h MICA v0.2 (Dec. 3rd 2007):
mica_utils.cpp Code refactoring memfootprint.
mica_utils.h Code refactoring memfootprint.


MICA: Microarchitecture-Independent Characterization of Applications
version 0.40

Kenneth Hoste & Lieven Eeckhout (Ghent University, Belgium)

with contributions by:
- Hamid Fadishei (multi-process support)
- Petr Tuma (code cleanup)
- Maxime Chéramy (cleanup, bug fixes, additional features)

website: (

A set of tutorial slides on MICA, which were presented at IISWC-2007 are
available from the MICA website.

* Disclaimer

This software was only tested on Linux/x86. Anyone who wants to use it on a different 
platform supported by Pin is free to do so, but should expect problems...

Any problem reports or questions are welcome at .

* Compilation

The easiest way to compile MICA is to add unzip/untar mica_vXYZ.tar.gz to the source/tools
directory of the Pin kit you are using. If you wish to place mica in a different
directory, you'll have to adjust the makefile included accordinly.
Running 'make' should produce the 'mica_v0-X' shared library.

By default, MICA is built using the GCC C++ compiler (g++).
Since Pin kit 39599 (March 2nd 2011), building Pin tools with the Intel compilers is
also supported. To build MICA using the Intel C++ compiler, run "make CXX=icpc".
Make sure /opt/intel/lib is added to the LD_LIBRARY_PATH environment variable to
use MICA built using the Intel compilers.

* Specifying type of analysis

MICA supports various types of microarchitecture-independent characteristics.
It also allows to measure the characteristics either for the entire execution, or
per interval of N dynamic instructions.

Specifying the parameters is done using the mica.conf configuration file. 
A sample mica.conf file is provided with the distribution, and details
on how to specify the parameters are found below.

analysis_type: all | ilp | ilp_one | itypes | ppm | reg | stride | memfootprint | memstackdist | custom
interval_size: full | <size>
[ilp_size: <size>]
[block_size: <2^size>]
[page_size: <2^size>]
[itypes_spec_file: <file>]


analysis_type: all
interval_size: 100000000
block_size: 6
page_size: 12
itypes_spec_file: itypes_default.spec

specifies to measure all supported characteristics per interval of 100,000,000 instructions,
with block size of 64 (2^6), page size of 4K (2^12), and using the instruction mix categories
described in the file itypes_default.spec

* Usage

Using MICA is very easy; just run:

pin -t -- <program> [<parameter>]

The type of analysis is specified in the mica.conf file, and some
logging is written to mica.log.

* Output files

(I realize the output file names are a bit strange, but that's just the way I
chose them... It's easy to adjust them yourself! ).

	full: ilp_full_int_pin.out
	interval: ilp_phases_int_pin.out
	full: ilp<size>_full_int_pin.out
	interval: ilp<size>_phases_int_pin.out
	full: itypes_full_int_pin.out
	interval: itypes_phases_int_pin.out
	full: ppm_full_int_pin.out
	interval: ppm_phases_int_pin.out
	full: reg_full_int_pin.out
	interval: reg_phases_int_pin.out
	full: stride_full_int_pin.out
	interval: stride_phases_int_pin.out
	full: memfootprint_full_int_pin.out
	interval: memfootprint_phases_int_pin.out
	full: memstackdist_full_int_pin.out
	interval: memstackdist_phases_int_pin.out

* Full execution metrics

+++ ilp +++

Instruction-Level Parallellism (ILP) available for four different instruction
window sizes (32, 64, 128, 256).  
This is measured by assuming perfect caches, perfect branch prediction, etc.  
The only limitations are the instruction window size and the data dependences.

analysis_type: ilp

Besides measuring these four window sizes at once, MICA also supports
specifying a single window size, which is specified as follows (for 
characterizing the full run using an instruction window of 32 entries):

analysis_type: ilp_one
interval_size: full
ilp_size: 32

You can tweak the block size used using the block_size configuration parameter.

+++ itypes +++

analysis_type: itypes

Instruction mix.

The instruction mix is evaluated by categorizing the executed instructions.
Because the x86 architecture isn't a load-store architecture, we count memory
reads/writes seperately. The following categories are used by default (in order 
of output):

- memory read (instructions which read from memory)
- memory write (instructions which write to memory)
- control flow
- arithmetic
- floating-point
- stack
- shift
- string
- sse
- other
- nop

It is possible to redefine the instruction mix categories, by creating a specification
file and mentioning it in the mica.conf file (itypes_spec_file).

+++ ppm +++

analysis_type: ppm

Branch predictability. 

The branch predictability of the conditional branches in the program is
evaluated using a Prediction-by-Partial-Match (PPM) predictor, in 4 different
configurations (global/local branch history, shared/seperate prediction
table(s)), using 3 different history length (4,8,12 bits).  Additionally,
average taken and transition count are also being measured.

+++ reg +++

analysis_type: reg

Register traffic.

The register traffic is analyzed in different aspects:

- average number of register operands
- average degree of use
- dependency distances (prob. <= D)

Dependency distances are chosen in powers of 2, i.e. 1, 2, 4, 8, 16, 32, 64

+++ stride +++

analysis_type: stride

Data stream strides.

The distances between subsequent memory accesses are characterised by:

- local load (memory read) strides
- global load (memory read) strides
- local store (memory write) strides
- global store (memory write) strides

Local means per static instruction accesses, global means over all
instructions. The strides are characterized by powers of 8 (prob. <= 0, 8, 64,
512, 4096, 32768, 262144)

+++ memfootprint +++

analysis_type: memfootprint

Instruction and data memory footprint.

The size of the instruction and data memory footprint is characterized by
counting the number of blocks (64-byte) and pages (4KB) touched. This
is done seperately for data and instruction addresses.

+++ memstackdist +++

analysis_type: memstackdist

Memory reuse distances.

This is a highly valuable set of numbers to characterize the cache behavior
of the application of interest. For each memory read, the corresponding
64-byte cache block is determined. For each cache block accessed, the number
of unique cache blocks accessed since the last time it was referenced is 
determined, using a LRU stack. 
The reuse distances for all memory reads are reported in buckets. The first
bucket is used for so called 'cold references'. The subsequent buckets capture reuse 
distances of [2^n, 2^(n+1)[, where n ranges from 0 to 18. The first of these
actually captures [0,2[ (not [1,2[), while the last bucket, [2^18, 2^19[, captures all 
reuse distances larger then or equal to 2^18, so it's in fact [2^18, oo[.
In total, this delivers 20 buckets, and the total number of memory accesses 
(the first number in the output), thus 21 numbers.

For example: the fifth bucket, corresponds to accesses with reuse distance
between 2^3 and 2^4 (or 8 64-byte cache blocks to 16 64-byte cache blocks).

Note: because memory addresses vary over different executions of the same
program, these numbers may vary slightly across multiple runs. Please be aware 
of this when using these metrics for research purposes.

To track the progress of the MICA analysis being run, see the mica_progress.txt tool 
which shows how many dynamic instructions have been analyzed. Disabling this can be
done by removing the -DVERBOSE flag in the Makefile and rebuilding MICA. 

* Interval metrics

Besides characterization total program execution, the tool is also capable of
characterizing interval behavior.  The analysis are identical to the tools
above, but flush the state for each new each interval.

+++ ilp +++

RESET: instruction and cycle counters (per interval), free memory used for
memory address stuff (to avoid huge memory requirements for large workloads)

DON'T TOUCH: instruction window contents; global instruction and cycle counters

+++ itypes +++

RESET: instruction type counters

+++ ppm +++

RESET: misprediction counts, taken/transition counts

DON'T TOUCH: branch history tables

+++ reg +++

RESET: operand counts, register use distribution and register age distribution

DON'T TOUCH: register use counts (i.e. keep track of register use counts across
interval boundaries); register definition addresses

+++ stride +++

RESET: instruction counts (, mem.write, interval), distribution counts

DON'T TOUCH: last (global/local) read/write memory addresses

+++ memfootprint +++

RESET: reference counters, free memory used for memory address stuff (to avoid
huge memory requirements for large workloads) 


+++ memstackdist +++

RESET: bucket counts (including cold reference and memory access counts)

DON't TOUCH: LRU stack (keep track of reuse distances over interval boundaries)

* Measured in integer values, convert to floating-point

Because of historical reasons (problems with printing out floating-point
numbers in certain situations with previous Pin kits), we only print out
integer values and convert to floating-point metrics offline. This also allows
aggregating data measured per interval to larger intervals or full execution
for most characteristics.

S: interval size
N: number of intervals
I: number of instructions

+++ ilp +++





1 to (N-1)th line: S/cycle_count_win_size_i
Nth line: (I-N*S)/cycle_count_win_size_i

+++ itypes +++






Note that simply adding the (n-1) last numbers won't necceseraly yield the first number.
First of all, the memory read and write counts shouldn't be added to the total, because
the x86 architecture is not a load/store architecture (e.g. an instruction can both read
memory and be a floating-point instruction).
Secondly, some instructions may fit in multiple categories, and therefore simply adding the
counts for the various categories will cause instructions to be counted double.

Also note that the (sum of) instruction_cnt value(s) will not match the instruction count 
printed at the last line of the output file ("number of instructions: <int>"). This is because
in the former, each iteration of a REP-prefixed instruction is counted, while in the latter
a REP-prefixed instruction in only counted once.

The other_cnt contains the number of instructions that did not fit in any of the other categories
(excluding mem_read and mem_write). More details on which kind of instructions this includes can
be found in the itypes_other_group_categories.txt output file.

+++ ppm +++





+++ reg +++





+++ stride +++





+++ memfootprint +++

Integer output (no conversion needed).



+++ memstackdist +++





* Multi-process binaries

If you want to use MICA on multiprocess binaries which call fork and execv, you should specify this entry in the MICA configuration file:

append_pid: yes

This will tell MICA to append the current process ID to the report file names so multiple processes do not overwrite each other's output.
Additionally, you should pass "-follow_execv 1" parameter to pin in order to trace multiprocess applications.
Something went wrong with that request. Please try again.