ZivYam
ZivYam

Reputation: 3

How to count how many times a global variable was used (read and write)?

I'm trying to optimize a C code project.

I would like to count how many times a global variable was used (read or write) in order to place it at the most suitable memory type.
For example, to store commonly used variables at the fast access memory type.

Data cache is disabled for determenistic reasons.

Is there a way to count how many times a variable was used without inserting counters or adding extra code? for example, using the assembly code?

The code is written in C.

In my possession:

A) (.map) file, generated by the GCC compiler from which I extracts the global variables names, addresses and sizes.

B) The assembly code of the project generated using the GCC compiler -S flag.

Thanks a lot,

Upvotes: 0

Views: 387

Answers (3)

Vladislav Ivanishin
Vladislav Ivanishin

Reputation: 2172

I think, what you need is automatic instrumentation and/or profiling. GCC can actually do profile-guided optimization for you. As well as other types of instrumentation, the documentation even mentions a hook for implementing your own custom instrumentation.

There are several performance analysis tools out there such as perf and gprof profilers.

Also, execution inside a virtual machine could (at least in theory) do what you are after. valgrind comes to mind. I think, valgrind actually knows about all memory accesses. I'd look for ways to obtain this informaiton (and then corellate that with the map files).

I don't know if any of the above tools solves exactly your problem, but you definitely could use, say, perf (if it's available for your platform) to see in what areas of code significant time is spent. Then probably there are either a lot of expensive memory accesses, or just intensive computations, you can figure out which is the case by staring at the code.

Note that the compiler already allocates frequently accessed variables to registers, so the kind of information you are after won't give you an accurate picture. I.e. while some variable might be accessed a lot, cache-allocating it might not improve things much if its value already lives on a register most of the time.

Also consider that optimization affects your program greatly on the assembly level. So any performance statistics such as memory accesses counters would be different with and without optimization. And what should be of interest to you is the optimized case. On the other hand, restoring the information about what location corresponds to which variable is harder with the optimized program if feasible at all.

Upvotes: 0

Andreas
Andreas

Reputation: 5301

GDB has something called watchpoints: https://sourceware.org/gdb/onlinedocs/gdb/Set-Watchpoints.html

Set a watchpoint for an expression. GDB will break when the expression expr is written into by the program and its value changes. The simplest (and the most popular) use of this command is to watch the value of a single variable:

(gdb) watch foo

awatch [-l|-location] expr [thread thread-id] [mask maskvalue]

Set a watchpoint that will break when expr is either read from or written into by the program.

Commands can be attached to watchpoints: https://sourceware.org/gdb/onlinedocs/gdb/Break-Commands.html#Break-Commands

You can give any breakpoint (or watchpoint or catchpoint) a series of commands to execute when your program stops due to that breakpoint… For example, here is how you could use breakpoint commands to print the value of x at entry to foo whenever x is positive.

break foo if x>0 
commands 
silent 
printf "x is %d\n",x 
cont 
end

The command should typically increment a variable or print "read/write" to a file, but you can really add other stuff too such as a backtrace. Unsure about the best way for outward communication using gdb. Maybe it is good enough for you to run it in interactive mode.

Upvotes: 0

Dominique
Dominique

Reputation: 17565

You can do this, using Visual Studio (or an other IDE): search for all places where your variable is used in the source code, put a conditional breakpoint, logging some information, attach to process, and launch the features which use that variable. You can count the instances in the output window.

Upvotes: 0

Related Questions