Any time your source code exceeds a few thousand lines, tracing becomes essential. It is important for
debugging, maintaining, and understanding execution flow of nontrivial software. You would not expect a
trace discussion in a performance book but the reality is, on more than one occasion, we have run into
severe performance degradation due to poor implementations of tracing. Even slight inefficiencies can
have a dramatic effect on performance. The goal of this chapter is not necessarily to teach proper trace
implementation, but to use the trace vehicle to deliver some important performance principles that often
surface in C++ code. The implementation of trace functionality runs into typical C++ performance
obstacles, which makes it a good candidate for performan ce discussion. It is simple and familiar. We don't
have to drown you in a sea of irrelevant details in order to highlight the important issues. Yet, simple or
not, trace implementations drive home many performance issues that you are likely to encounter in any
random fragment of C++ code.
Many C++ programmers define a simple Trace class to print diagnostic information to a log file.
Programmers can define a Trace object in each function that they want to trace, and the Trace class can
write a message on function entry and function exit. The Trace objects will add extra execution overhead,
but they will help a programmer find problems without using a debugger. If your C++ code happens to be
embedded as native code in a Java program, using a Java debugger to trace your native code would be a
challenge.
The most extreme form of trace performance optimization would be to eliminate the performance cost
altogether by embedding trace calls inside #ifdef blocks:
Running Codes
#ifdef TRACE
Trace t("myFuction"); // Constructor takes a function name argument
t.debug("Some information message");
#endif
int myFunction(int x)
{
string name = "myFunction";
Trace t(name);
...
string moreInfo = "more interesting info";
t.debug(moreInfo);
...
}; // Trace destructor logs exit event to an output stream
class Trace {
public:
Trace (const string &name);
~Trace ();
void debug (const string &msg);
static bool traceIsActive;
private:
string theFunctionName;
};
inline
Trace::Trace(const string &name) : theFunctionName(name)
{
if (TraceIsActive) {
cout << "Enter function" << name << endl; } }
http://www.fortran-2000.com/ArnaudRecipes/CompilerTricks.htmlTrace t("myFuction"); // Constructor takes a function name argument
t.debug("Some information message");
#endif
int myFunction(int x)
{
string name = "myFunction";
Trace t(name);
...
string moreInfo = "more interesting info";
t.debug(moreInfo);
...
}; // Trace destructor logs exit event to an output stream
class Trace {
public:
Trace (const string &name);
~Trace ();
void debug (const string &msg);
static bool traceIsActive;
private:
string theFunctionName;
};
inline
Trace::Trace(const string &name) : theFunctionName(name)
{
if (TraceIsActive) {
cout << "Enter function" << name << endl; } }
http://www.pearsonhighered.com/educator/product/Efficient-C-Performance-Programming-Techniques/9780201379501.page
No comments:
Post a Comment