Note: This version is outdated.
Please contact (tommy [dot] janjusic [at] gmail [dot] com) (Tommy), for more info.

 

If you are unfamiliar with Valgrind we suggest that you at least get a basic understanding of how Valgrind works.

Basic Run

Let's get a basic understanding of Gleipnir's output by running the following code:

#include "/home/janjust/research/valgrind_src/gleipnir/gleipnir.h"

struct typeA{
  double var1;
  int myArray[10];
};

struct typeA GlStrc;
struct typeA glStrcArray[10];

int glScalar;
int glArray[10];

void func(struct typeA StrcParam[])
{
  int i;

  for(i=0; i<3; i++){
    glStrcArray[i].var1 = glScalar;
    glStrcArray[i].myArray[0] = glArray[0];
    StrcParam[i].var1 = glArray[i];
  }
  return;
}

int main(void)
{
  GL_START_INSTR;

  struct typeA lcStrcArray[5];
  int i, lcScalar, lcArray[10];

  glScalar = 10;
  lcScalar = 20;

  for(i=0; i<2; i++)
    lcArray[i] = glScalar;

  func(lcStrcArray);
  
  GL_STOP_INSTR;
  
  return 0;
}

 

Compile the code with debug options enabled

 $ gcc -g code.c -o code.out 

 

Assuming everything compiled and is running you can run gleipnir as follows:

 $ $valgrind/src/bin/valgrind --read-var-info=yes --tool=gleipnir ./path/code.out 

 

You should see the following output:

==517== Gleipnir, a Valgrind tool
==517== Copyright (C) 2011-2012, and GNU GPL'd, by Computer Systems Research Laboratory
==517== University of North Texas, Denton Texas.
==517== Using Valgrind-3.9.0.SVN and LibVEX; rerun with -h for copyright info
==517== Command: ./a.out
==517== 
==517== 

 

Gleipnir will generate a trace file in the form gleipnir.pid; where pid is the process ID.

janjust@fenrir:~/research/valgrind_build/bin$ ls
callgrind_annotate callgrind_control cg_annotate cg_diff cg_merge gleipnir.out.517 ms_print valgrind valgrind-listener vgdb
janjust@fenrir:~/research/valgrind_build/bin$ 

 

The trace files can get rather large, this simple program produced a ~4MB trace file with roughly ~150k lines. 
These traces are Load, Store and Instruction traces interleaved, if it is of little interest then the Instruction traces may be suppressed.

To get an idea of Gleipnir's output, look at the trace snippet below:

START PID 517
X THREAD_CREATE 0:1
S 7ff000490 8 1 S main LV _zzq_result
L 7ff000490 8 1 S main
S 000601070 4 1 G main GV glScalar
S 7ff00049c 4 1 S main LV lcScalar
S 7ff000498 4 1 S main LV i
L 7ff000498 4 1 S main LV i
L 000601070 4 1 G main GV glScalar
L 7ff000498 4 1 S main LV i
S 7ff000460 4 1 S main LS lcArray[0]
M 7ff000498 4 1 S main LV i
L 7ff000498 4 1 S main LV i
L 000601070 4 1 G main GV glScalar
L 7ff000498 4 1 S main LV i
S 7ff000464 4 1 S main LS lcArray[1]
M 7ff000498 4 1 S main LV i
L 7ff000498 4 1 S main LV i
S 7ff000330 8 1 S main
S 7ff000328 8 1 S func
S 7ff000310 8 1 S func LV StrcParam
S 7ff000324 4 1 S func LV i
L 7ff000324 4 1 S func LV i
L 000601070 4 1 G func GV glScalar
L 7ff000324 4 1 S func LV i
S 000601080 8 1 G func GS glStrcArray[0].var1
L 000601260 4 1 G func GS glArray[0]
L 7ff000324 4 1 S func LV i
S 000601088 4 1 G func GS glStrcArray[0].myArray[0]
L 7ff000324 4 1 S func LV i
L 7ff000310 8 1 S func LV StrcParam
L 7ff000324 4 1 S func LV i
L 000601260 4 1 G func GS glArray[0]
S 7ff000340 8 1 S func LS lcStrcArray[0].var1
M 7ff000324 4 1 S func LV i
L 7ff000324 4 1 S func LV i
L 000601070 4 1 G func GV glScalar
L 7ff000324 4 1 S func LV i
S 0006010b0 8 1 G func GS glStrcArray[1].var1
L 000601260 4 1 G func GS glArray[0]
L 7ff000324 4 1 S func LV i
S 0006010b8 4 1 G func GS glStrcArray[1].myArray[0]
L 7ff000324 4 1 S func LV i
L 7ff000310 8 1 S func LV StrcParam
L 7ff000324 4 1 S func LV i
L 000601264 4 1 G func GS glArray[1]
S 7ff000370 8 1 S func LS lcStrcArray[1].var1
M 7ff000324 4 1 S func LV i
L 7ff000324 4 1 S func LV i
L 000601070 4 1 G func GV glScalar
L 7ff000324 4 1 S func LV i
S 0006010e0 8 1 G func GS glStrcArray[2].var1
L 000601260 4 1 G func GS glArray[0]
L 7ff000324 4 1 S func LV i
S 0006010e8 4 1 G func GS glStrcArray[2].myArray[0]
L 7ff000324 4 1 S func LV i
L 7ff000310 8 1 S func LV StrcParam
L 7ff000324 4 1 S func LV i
L 000601268 4 1 G func GS glArray[2]
S 7ff0003a0 8 1 S func LS lcStrcArray[2].var1
M 7ff000324 4 1 S func LV i
L 7ff000324 4 1 S func LV i
L 7ff000328 8 1 S func
L 7ff000330 8 1 S func
S 7ff000430 8 1 S main LS _zzq_args[0]
S 7ff000438 8 1 S main LS _zzq_args[1]
S 7ff000440 8 1 S main LS _zzq_args[2]
S 7ff000448 8 1 S main LS _zzq_args[3]
S 7ff000450 8 1 S main LS _zzq_args[4]
S 7ff000458 8 1 S main LS _zzq_args[5]
S 7ff00033c 4 1 S main
L 7ff00033c 4 1 S main

 

The traces are all the instructions(L/S/M/I) (and a few extra :-/) which were executed during the code.out program run. Their virtual addresses are mapped back to their source code variables. The idea is to use these traces in trace driven cache simulators to produce graphical analyses of an application's cache behavior.

As part of the Gleipnir tool we have modified DineroIV for Gleipnir targeted cache simulation.