This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

SystemTap upcoming feature: suppressed statement counting


Hello everyone,

I have been working on having SystemTap suppress statement
counting in the generated c code. Doing such was brought up
in PR16300. The goal of the email is to provide a bit of
detail and demonstrate where the benefits occur.

To implement this change, the focus was on determining if a
portion of code, whether a probe body or function, is free
of loops, or recursion.

In those cases, a check that the MAXACTION, whether default
or set, is greater than the body's approximated statement
count is emitted in replacement of action counting code.

Those cases are where the performance optimization can be
observed.

In the event that the function or probe body contains a
loop or recursion, the action counting code is emitted.

____
NOTE

This feature can be turned off by running the script in
unoptimized mode (-u).

_____
USAGE

To see a difference in how the feature impacts the
generated c code, I produced a script that focuses on
the use of if-else statements.

straight_through.stp
===========
# stap -t straight_through.stp 10 -c "ls"                                                
                                                                                
global num                                                                      
probe process.function("process_signals"){                                      
  if ($1 != func1($1))                                                          
    printf("\n");                                                              
  else {                                                                        
    num = func1($1);                                                            
    if (num < 0)                                                                
      printf("\n");                                                            
    else                                                                        
      printf("-");                                                              
  }                                                                            
}                                                                              
                                                                                
function func1 (a){                                                            
  if (a == 1) { printf("2");}                                                  
  else { printf(""); }                                                          
  if (a == 2) { printf("9");}                                                  
  else { printf(""); }                                                          
  if (a == 3) { printf("4");}                                                  
  else { printf(""); }                                                          
  if (a == 4) { printf("1");}                                                  
  else { printf(""); }                                                          
  if (a == 5) { printf("7");}                                                  
  else { printf(""); }                                                          
  if (a == 6) { printf("3");}                                                  
  else { printf(""); }                                                          
  if (a == 7) { printf("1");}                                                  
  else { printf(""); }                                                          
  if (a == 8) { printf("5");}                                                  
  else { printf(""); }                                                          
  if (a == 9) { printf("8");}                                                  
  else { printf(""); }                                                          
  if (a == 10) { printf("6");}                                                  
  else { printf(""); }                                                          
  return a;                                                                    
}

===========

Below is a portion of the generated c code for the function
in the script above, with the feature enabled (default setting).

 if (c->actionremaining < 21) { c->last_error = "MAXACTION too low"; goto out; }
  {
    if ((((l->l_a) == (((int64_t)1LL))))) {
      (void)
      ({
        _stp_print ("2");
      });
    }
    else {
      (void)
      ({
        _stp_print ("");
      });
    }
    
    if ((((l->l_a) == (((int64_t)2LL))))) {
      (void)
      ({
        _stp_print ("9");
      });
    }
    else {
      (void)
      ({
        _stp_print ("");
      });
    }

===========

For comparison, below is the same section of generated c code
in the script run in unoptimized mode (-u). This reflects what
the generated c code would look like before the feature
implementation.

    c->actionremaining -= 1;
    if (unlikely (c->actionremaining <= 0)) {
      c->last_error = "MAXACTION exceeded";
      c->last_stmt = "keyword at straight_through.stp:17:3";
      goto out;
    }
    if ((((l->l_a) == (((int64_t)1LL))))) {
      {
        (void)
        ({
          _stp_print ("2");
        });
        
      }
      c->actionremaining -= 1;
      if (unlikely (c->actionremaining <= 0)) {
        c->last_error = "MAXACTION exceeded";
        c->last_stmt = "operator '{' at straight_through.stp:17:15";
        goto out;
      }
    }
    else {
      {
        (void)
        ({
          _stp_print ("");
        });
        
      }
      c->actionremaining -= 1;
      if (unlikely (c->actionremaining <= 0)) {
        c->last_error = "MAXACTION exceeded";
        c->last_stmt = "operator '{' at straight_through.stp:18:8";
        goto out;
      }
    }
    
    c->actionremaining -= 1;
    if (unlikely (c->actionremaining <= 0)) {
      c->last_error = "MAXACTION exceeded";
      c->last_stmt = "keyword at straight_through.stp:19:3";
      goto out;
    }
    if ((((l->l_a) == (((int64_t)2LL))))) {
      {
        (void)
        ({
          _stp_print ("9");
        });
        
      }
      c->actionremaining -= 1;
      if (unlikely (c->actionremaining <= 0)) {
        c->last_error = "MAXACTION exceeded";
        c->last_stmt = "operator '{' at straight_through.stp:19:15";
        goto out;
      }
    }
    else {
      {
        (void)
        ({
          _stp_print ("");
        });
        
      }
      c->actionremaining -= 1;
      if (unlikely (c->actionremaining <= 0)) {
        c->last_error = "MAXACTION exceeded";
        c->last_stmt = "operator '{' at straight_through.stp:20:8";
        goto out;
      }
    }

===========

Running straight_through.stp with the -t flag for timing
information, with and without the -u flag gave some
varying results. On average, running the script with the
new feature enabled (default setting) produced average
cycle times that were smaller than the average cycle time
when running the script with -u.

>From running the script 15 times, the resulting average
cycle times for the probe are:
default: 750
unoptimized: 825

As mentioned before the test script provided focuses on the
use of if statements. This is to show the impact of the
feature. With code that contains loops or recursion, the impact
is less significant, to the point of not being present.

Further work can be done to optimize statement counting for
code that contains loops or recursion.

Any comments and/or feedback is always welcome.

Abegail Jakop


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]