IBM Mainframe Forum Index
 
Log In
 
IBM Mainframe Forum Index Mainframe: Search IBM Mainframe Forum: FAQ Register
 

cost of the CALL command


IBM Mainframe Forums -> COBOL Programming
Post new topic   Reply to topic
View previous topic :: View next topic  
Author Message
jctgf
Currently Banned

Active User


Joined: 04 Nov 2006
Posts: 109

PostPosted: Fri Sep 25, 2009 7:57 pm
Reply with quote

The wave in the company I work is to replace any little function in the program for another program, and access this new program through a CALL command.

This way, the number of CALLs in programs are increasing dramatically.

My questions: how harmful is the CALL command in terms of performance? Does it impact significantly the execution of a batch application? How about an online application? Does it cost the same as a PERFORM? Should I care about it?

I made some measurements and couldn't perceive any difference.

Thanks.
Back to top
View user's profile Send private message
dick scherrer

Moderator Emeritus


Joined: 23 Nov 2006
Posts: 19244
Location: Inside the Matrix

PostPosted: Fri Sep 25, 2009 11:40 pm
Reply with quote

Hello,

Once the code is loaded into memory, a CALL and a PERFORM use about the same resources.
Quote:
Should I care about it?
Probably not - especially as you've made some measurements and don't see any difference icon_smile.gif
Back to top
View user's profile Send private message
MBabu

Active User


Joined: 03 Aug 2008
Posts: 400
Location: Mumbai

PostPosted: Sat Sep 26, 2009 11:15 am
Reply with quote

It really depends on the environment and the type of call. If the CALL is going to an external program and there are many parameters then the setup and linkage can be fairly expensive. If the call is not to the same load module (static?) then the system has to search the job pack area, possibly the link list and LPA as well. But even if it is local, the call can be more expensive than a local subroutine because the called program is probably going to do a getmain/freemain or similar to get/free working storage. It is very unlikely that your measurements will see a difference, but scaled up to many jobs, it can significantly affect performance system wide if the system is heavily loaded and the calls are frequent enough. I've seen (more to the point, I've caused) severe problems by making frequent calls to small modules. But that was 20 years ago and processors are much faster now.

I will point out that this tendency to use lots of small programs seems to come from people who have programming experience in languages that use a stack and heap ratherthan the z/OS memory model. In C, for example getting storage is just a single pointer increment pointing into the stack. Hence the fact that a zillion little routines are used in C doesn't really matter. MVS isn't that simple. In most cases it is very efficient, but not as efficient as a simple stack or heap.
Back to top
View user's profile Send private message
jctgf
Currently Banned

Active User


Joined: 04 Nov 2006
Posts: 109

PostPosted: Fri Oct 09, 2009 12:00 am
Reply with quote

Follows what I've found in an IBM paper:


Performance considerations for using CALLs (measuring CALL overhead only):
CALL to nested programs was 50% to 60% faster than static CALL.
Static CALL literal was 45% to 55% faster than dynamic CALL literal.
Static CALL literal was 60% to 65% faster than dynamic CALL identifier.
18 IBM Enterprise COBOL Version 3 Release 1 Performance Tuning
Dynamic CALL literal was 15% to 25% faster than dynamic CALL identifier.
Note: These tests measured only the overhead of the CALL (i.e., the subprogram did only a GOBACK);
thus, a full application that does more work in the subprograms may have different results.
Back to top
View user's profile Send private message
dick scherrer

Moderator Emeritus


Joined: 23 Nov 2006
Posts: 19244
Location: Inside the Matrix

PostPosted: Fri Oct 09, 2009 12:26 am
Reply with quote

Hello,

As the paper mentions, there is some different % improvement when different choices are made. Unfortunately, this does not provide much for making a decision.

If the CALLs used in a process use only an unmeasurable amount of overhead, a 60 (or even 80) percent improvement will still probably not be measurable. . .

fwiw. . .
Back to top
View user's profile Send private message
Bill O'Boyle

CICS Moderator


Joined: 14 Jan 2008
Posts: 2501
Location: Atlanta, Georgia, USA

PostPosted: Fri Oct 09, 2009 12:28 am
Reply with quote

Years ago, I had experimented with PROCEDURE-POINTER in Batch, which loads (under the covers) the target dynamic sub-program into memory (very similar to an MVS LOAD Macro). The given sub-program was Called millions of times from the Batch caller and I was looking for some CPU reduction.

Afterwards, I used the entry point address (the PROCEDURE-POINTER value) in the CALL instead of the sub-program name and it resulted in less CPU.

In 2008, I met an IBM COBOL compiler guy at Share-Orlando and explained this to him. His reply was "must have hit some Blue code", which I took as undocumented IBM logic.

PROCEDURE-POINTER should NEVER be used in CICS. Instead, use the LOAD PROGRAM API.

PROCEDURE-POINTER was introduced with COBOL/370, in the early 1990's.

Bill
Back to top
View user's profile Send private message
Robert Sample

Global Moderator


Joined: 06 Jun 2008
Posts: 8697
Location: Dubuque, Iowa, USA

PostPosted: Fri Oct 09, 2009 12:37 am
Reply with quote

Quote:
I made some measurements and couldn't perceive any difference.
Not surprising -- I wouldn't expect a large difference for as many as several thousand CALL statements. For a few million executions, I would expect to start seeing some big differences -- possibly affecting the batch window. I've got a test program that adds 1 to a counter 10 million times. Our z800 runs this COBOL code in 3 seconds (.05 minutes) of CPU time, and z10 machines are 6 times faster. Unless your measurements were carefully designed and measuring millions of operations, you're not likely to see enough difference to be able to notice it.
Back to top
View user's profile Send private message
jctgf
Currently Banned

Active User


Joined: 04 Nov 2006
Posts: 109

PostPosted: Fri Oct 09, 2009 5:40 am
Reply with quote

Bill O'Boyle wrote:
Years ago, I had experimented with PROCEDURE-POINTER in Batch, which loads (under the covers) the target dynamic sub-program into memory (very similar to an MVS LOAD Macro). The given sub-program was Called millions of times from the Batch caller and I was looking for some CPU reduction.

Afterwards, I used the entry point address (the PROCEDURE-POINTER value) in the CALL instead of the sub-program name and it resulted in less CPU.

In 2008, I met an IBM COBOL compiler guy at Share-Orlando and explained this to him. His reply was "must have hit some Blue code", which I took as undocumented IBM logic.

PROCEDURE-POINTER should NEVER be used in CICS. Instead, use the LOAD PROGRAM API.

PROCEDURE-POINTER was introduced with COBOL/370, in the early 1990's.

Bill


When you say "procedure-pointer" do you mean "entry-points" in the procedure divison?
Back to top
View user's profile Send private message
Bill O'Boyle

CICS Moderator


Joined: 14 Jan 2008
Posts: 2501
Location: Atlanta, Georgia, USA

PostPosted: Fri Oct 09, 2009 7:59 am
Reply with quote

Yes, using PROCEDURE-POINTER will return the main entry point of the target program (CSECT) and should NOT be confused with POINTER, which was introduced with VS/COBOL II in the mid/late 1980's.

However, I'm unsure whether you can use PROCEDURE-POINTER to return an alternate entry-point. I guess it would depend on the target ENTRY value in the actual SET PROCEDURE-POINTER statement.

Substituting a sub-program, which issued an MVS LOAD Macro with a PROCEDURE-POINTER, did make life easier in shops where Assembler expertise had dwindled or had become non-existent.

Using PROCEDURE-POINTER to reduce CPU (in the above experiment) was a yield which was not anticipated, but was certainly welcomed.

Bill
Back to top
View user's profile Send private message
jctgf
Currently Banned

Active User


Joined: 04 Nov 2006
Posts: 109

PostPosted: Fri Oct 09, 2009 7:59 pm
Reply with quote

jctgf wrote:
Follows what I've found in an IBM paper:


Performance considerations for using CALLs (measuring CALL overhead only):
CALL to nested programs was 50% to 60% faster than static CALL.
Static CALL literal was 45% to 55% faster than dynamic CALL literal.
Static CALL literal was 60% to 65% faster than dynamic CALL identifier.
18 IBM Enterprise COBOL Version 3 Release 1 Performance Tuning
Dynamic CALL literal was 15% to 25% faster than dynamic CALL identifier.
Note: These tests measured only the overhead of the CALL (i.e., the subprogram did only a GOBACK);
thus, a full application that does more work in the subprograms may have different results.


The text above mentions "dynamic call literal".
I wonder if they are talking about the call to a subprogram which name is between quotes, and the caller has the compiler option DYNAMIC. Example:

Code:

   CBL DYNAMIC
   IDENTIFICATION DIVISON.
   PROGRAM-ID. CALLER.
      ...
   PROCEDURE DIVISION.
   CALL 'CALLED' USING P1.
   STOP RUN.



Quote:

However, I'm unsure whether you can use PROCEDURE-POINTER to return an alternate entry-point. I guess it would depend on the target ENTRY value in the actual SET PROCEDURE-POINTER statement.


Bill,

Your level of expertise is to high for me.

I wonder if you're suggesting that calling entry-points is faster than calling the program-id.

If so, it's going to be very useful for us because we:

1-call the subprogram program-id;
2-test the function code passed to the subprogram;
3-execute only a section of the subprogram;
4-go back to the caller.

Called subprogarm procedure divison:
Code:

PROCEDURE DIVISON.
EVALUETE FUNCTION-CODE
WHEN 01
          PERFORM FUNCTION-01
WHEN 02
          PERFORM FUNCTION-02
WHEN ...
END-EVALUATE.
GOBACK.


FUNCTION-01 SECTION.
...

FUNCTION-02 SECTION.
...

FUNCTION... SECTION.
... 



We have many applications with a very bad performance. Most of the problem is due to DB2 access but I suspect that a good amount of this is caused by massive use dynamic calls.

Thanks.
Back to top
View user's profile Send private message
Bill O'Boyle

CICS Moderator


Joined: 14 Jan 2008
Posts: 2501
Location: Atlanta, Georgia, USA

PostPosted: Fri Oct 09, 2009 8:47 pm
Reply with quote

As you've surmised, there can be a big difference in CALL-Time between a Statically Called and Dynamically-Called sub-program, with Statically Called being much more efficient, but with potential issues.

Statically Called sub-programs are merged together with the Caller, forming a single load-module, whereas, Dynamically Called sub-programs are separate load-modules.

It really comes down to maintenance and the number of potential times a sub-program is changed.

If the sub-program is changed infrequently, then it could be a candidate for a Static Call, whereas, if the sub-program is changed on a regular basis, then it would probably make more sense that it should be Called Dynamically.

However, if you're using sub-programs in a dual-mode environment, where they can be called in both Batch and CICS (no CICS commands in the given sub-program) and the CICS Call is Static, then WS needs to be passed by the serially-reusable Caller, for use by the sub-program. By doing this, you'll eliminate one issue (probably of many) of migrating your applications to Threadsafe/OpenAPI, which is IBM's statement of direction for CICS.

But, if the parmlist can't be changed and you would like to be Threadsafe compliant in a Static Call environment, then review EXTERNAL storage, which was introduced with VS/COBOL II about 20 years ago. External storage allows all program's in the run-unit (all programs associated with a given transaction) to access this same EXTERNAL storage.

Statically Called sub-programs, which don't contain reentrant-storage, cannot be made Threadsafe compliant (multiple TCB's accessing the sub-program concurrently) until the storage is deemed reentrant. Otherwise, many "opportunities" will be raised and you would want to avoid these. icon_wink.gif

Statically Called COBOL programs, which don't utilize reentrant WS are akin to Called Assembler sub-programs (regardless whether they are Static or Dynamic). You can certainly pass COBOL WS to an Assembler sub-program. Note that this "heads-up" is for CICS environments only as Batch environments shouldn't have these issues.

In addition, regardless whether a CICS sub-program is called Dynamically or Statically, it inherits the PPT characteristics of the Caller. So, if the Caller is defined as Threadsafe, all sub-programs accessed by the Caller must be Threadsafe compliant as well.

Bill
Back to top
View user's profile Send private message
View previous topic :: :: View next topic  
Post new topic   Reply to topic View Bookmarks
All times are GMT + 6 Hours
Forum Index -> COBOL Programming

 


Similar Topics
Topic Forum Replies
No new posts RACF - Rebuild SETROPTS command which... All Other Mainframe Topics 3
No new posts Routing command Address SDSF to other... TSO/ISPF 2
No new posts DTL - how to define key with stacked ... TSO/ISPF 3
No new posts LTJ command CA Products 4
No new posts RACF cost vs. ACF2 cost IBM Tools 2
Search our Forums:

Back to Top