Instrumenting the sources for Profiling
Adding Profiling calls to the functions ensures the profiling data is
generated for that function. A function is uniquely identified by its name and
its arguments types i.e., a string comprising of its return type and the type of
its arguments.
Adding Instrumentation
Within the application, use the Profiling API for all the functions that need to be profiled.
TAU_PROFILE(char *func_name, char *type_info, uint profile_group);
TAU_TYPE_STRING(string_varname, cstring& str);
TAU_PROFILE_TIMER(var, name, type, group);
TAU_PROFILE_START(var);
TAU_PROFILE_STOP(var);
TAU_PROFILE_STMT(stmt);
TAU_PROFILE_INIT(argc, argv);
TAU_PROFILE_SET_NODE(myNode);
TAU_PROFILE_EXIT(const char *message);
In the application, several related functions can be grouped together to form a profile group
which can be selectively enabled for profiling at runtime. This is discussed at
length in the selective profiling section .
In the TAU_TYPE_STRING macro, the type string generated can be retrieved using string_varname for use in the second argument of TAU_PROFILE . TAU_PROFILE_STMT is used typically to declare a variable that is used only while profiling. TAU_PROFILE_INIT macro is used to set profile groups, while TAU_PROFILE_SET_NODE is used to set
the current node id (both are called by framework).
TAU_PROFILE_EXIT is called by any thread prior to calling exit() if it wants to dump the profiling data to disk before exiting.
|
For e.g.,
int main(int argc, char **argv)
{
TAU_PROFILE("main", "int (int, char **)", TAU_DEFAULT);
TAU_PROFILE_TIMER(timer1,"main-loop1", "int (int, char **)", TAU_USER);
TAU_PROFILE_TIMER(timer2,"main-loop2", "int (int, char **)", TAU_USER);
TAU_PROFILE_START(timer1);
for(i=0; i < N; i++) { // loop1 profiled using timer1 var }
TAU_PROFILE_STOP(timer1);
...
TAU_PROFILE_START(timer2);
for(j=0; j < N; j++) { //loop2 profiled using timer2 var }
TAU_PROFILE_STOP(timer2);
...
}
template <class T>
class MyClass {
public :
T Data;
int MyFunc(T * x) {
TAU_PROFILE("MyClass::Myfunc", typeid(MyFunc).name(), TAU_USER1);
// Or use typeid(*this).name() in to get type info of class
... }
// member template of a class template
template <class Dim>
T SetDataTemplMem (Dim dimen, T dat) {
TAU_TYPE_STRING(p1, CT(Data) + " (" + CT(dimen) + ", " + CT(dat) + ")");
// produces a string like "int (int, double)" at runtime
TAU_PROFILE("TemplClass::SetDataTemplMem()", p1, TAU_USER2);
Data = dat * dimen;
return Data;
}
};
This example is covered in greater detail in the examples section later.
Note: The use of TAU_TYPE_STRING
macro is highly recommended
over using sprintf
to generate strings because it adds no
runtime overhead when profiling is disabled. In addition, TAU_TYPE_STRING
is executed only once for each function while the strings generated can be of any arbitrary
length.
Compiling and Running the Profiled Application
Compile the library, pprof
and the application.
% cd $(POOMA_ROOT)/lib/$(POOMA_ARCH)
% make
% cd $(POOMA_ROOT)/src/Profile/utils
% make
|
Settings for pprof
and racy
Add to your .cshrc file
# in .cshrc file
set path=($path $POOMA_ROOT/src/Profile/utils)
# For racy to see the Profile data on ACL SGI machines
set path=($path /usr/local/packages/tau/bin/sgi8k)
# setenv PROFILEDIR ./data
|
PROFILEDIR
environment variable specifies the location where profile files are
stored (default is the current directory).
Make the application
% cd $(POOMA_ROOT)/test/particle
% make PIC2d
And Run the application
% mpirun -np 8 PIC2d --commlib mpi
|
This generates files named profile.[node].[context].[thread] e.g., profile.7.0.0
.