Are you looking for ways to improve the performance of your ILE applications? If so, you should look at Chapter 13 of IBM i ILE Concepts (SC41-5606), which describes several advanced optimization techniques you can try. Today, I’d like to discuss one of these topics: improving procedure call performance with Argument Optimization.
Argument optimization may help if you have one or more procedure calls that are invoked frequently, particularly if they pass or return space pointers. A space pointer is just a pointer to user data; in C or C++, examples of space pointers include int* and char*. Argument optimization makes passing space pointers more efficient.
Because space pointers are large and contain validity tags to avoid malicious or accidental misuse, they usually must be passed in memory on procedure calls. Contrast this with an integer value, which can be passed in a register. Access to registers is much faster than access to memory. The primary purpose of argument optimization is to make the cost of passing a space pointer about the same as the cost of passing an integer.
Simple Argument Optimization
How is this accomplished? The key point is that sometimes the extra integrity information in a space pointer isn’t needed. The optimizing translator can prove this by itself for the simplest cases. For example, consider the case where procedure X calls procedure Y, both X and Y reside in the same module, and Y isn’t exported so it can’t be called from another module. When compiling procedure Y, the translator knows that Y is only called with space pointers whose values couldn’t have been changed since they were previously validated. For those cases, there’s no need to again validity check the space pointer when it’s passed as an argument. The translator changes Y to expect a simpler form of the space pointer in a register, and changes X to pass the corresponding parameter using the same simpler form.
This transformation makes the procedure call noticeably faster. The problem is that the translator doesn’t have enough information to make these decisions in every case. In the previous example, if Y can be called from outside its module, the translator can’t be sure one of the callers may not pass in the wrong sort of pointer, so the pointer must be passed in memory and subjected to validity checking. This is because the translator only compiles one module at a time.
IBM provides two mechanisms allowing you to extend the benefits of argument optimization to more of your procedure calls. Both have different advantages and disadvantages, so you may want to use one or both methods, depending on your application.
The following table summarizes these differences:
The “#pragma argopt” alternative allows you to annotate individual procedures or procedure pointers to indicate that argument optimization should be used on them. You place the pragma following the declaration or definition of the procedure or procedure pointer. If procedure X in module M calls procedure Y in module N, you must be consistent in your usage of #pragma argopt for procedure Y in both modules. For more details, you can consult the ILE C/C++ Compiler Reference (SC09-4816).
The primary advantage of #pragma argopt is that it can be used on functions that are called indirectly through a procedure pointer. This includes C++ virtual function calls. As we’ll see, ARGOPT(*YES) doesn’t work on indirect calls. The disadvantages of #pragma argopt are that it requires source-code changes, and that it’s only supported in the ILE C and C++ compilers.
Advanced Argument Optimization
Advanced Argument Optimization was introduced in release 6.1 of the IBM i operating system. Remember the translator is able to automatically perform argument optimization for simple cases by analyzing the potential callers of a procedure. Advanced Argument Optimization extends this automatic use of argument optimization to an entire program or service program.
You request Advanced Argument Optimization on the CRTPGM and CRTSRVPGM commands by specifying the ARGOPT(*YES) parameter. The system then analyzes all of the procedure calls in every module being bound into the program or service program. This allows argument optimization to be used on almost all bound procedure calls in the program. The main exception is that procedures accessible from outside the program or service program can’t be argument optimized, because–once again–we can’t be sure all callers are making correct use of space pointers.
Advanced Argument Optimization doesn’t attempt to optimize virtual function calls, or other calls through procedure pointers. The use of procedure pointers makes it difficult or impossible to prove which procedures might be called via one of these pointers. Therefore, if your code contains indirect calls, you may want to use #pragma argopt for those calls, even when using ARGOPT(*YES).
The primary advantages of Advanced Argument Optimization are that no source changes are required, and all ILE languages are supported. The disadvantages are that indirect procedure calls aren’t optimized, and the time required to create or update your programs is longer. It takes more time to scan the modules and analyze which procedure calls can be argument optimized.
Should I Use Argument Optimization?
Whether or not argument optimization will help you depends on the nature of your application. The key question is whether you have procedures that are frequently called in your programs. If so, and if those procedures expect space pointers as parameters or return space pointers to their callers, then argument optimization could improve your application’s performance.
Note that if you create your modules with DTAMDL(*LLP64), your application will receive less benefit from argument optimization. With this data model, the smaller, more efficient pointers to data are already passed in registers. However, some applications may make explicit use of 16-byte space pointers in DTAMDL(*LLP64) modules, so you may still see some benefit.
I hope this has been useful to some of you! In a future blog entry, I’ll talk about another advanced optimization technique: Program Profiling.
I’d like to thank Bill Schmidt for writing this blog article. Bill is the team leader of the IBM i Optimizing Translator team.
This blog post was originally published on IBMSystemsMag.com and is reproduced here by permission of IBM Systems Media.