Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29277 Discussions

Do passing arguments to a subroutine slow its execution?

OP1
New Contributor III
1,515 Views

I am wondering if passing arguments (such as an user-defined error structure variable) to a computational subroutine called very often is going to slow down the execution of my code.
For instance, let's assume that I have the following subroutine:

SUBROUTINE CRUNCH_NUMBERS(X,ERROR_MSG,ERROR_SUB)
REAL(KIND=8),INTENT(INOUT) X(10000)
EXTERNAL ERROR_SUB
CHARACTER(100) ERROR_MSG
...
! Do some calculations here. If an error occurs (say, division by 0), execute:
CALL ERROR_SUB(ERROR_MSG)
...
END SUBROUTINE CRUNCH_NUMBERS

Now, if the CRUNCH_NUMBERSsubroutine is used very intensively (called very often), will the presence of the ERROR_MSG and ERROR_SUBslow down its performance?

Thanks,

Olivier

0 Kudos
6 Replies
jimdempseyatthecove
Honored Contributor III
1,515 Views

Oliver,

Each call will require one read and one write for each additional argument so 4 memory operations. Your X array is 10,000 elements. If each of these elements will get touched once you have 4/10,000 overhead (not counting the instructions to parse the array). Considering a simple operation on the array your overhead might be 1/10th this to 1/100th this. 4/100,000 to 4/1,000,000 of overhead.

On 64-bit platform these arguments will be passed in registers. Therefore the overhead is 1/2 the above.

Jim Dempsey
0 Kudos
OP1
New Contributor III
1,515 Views
Thanks Jim for your fast anwer. It doesn't seem too bad indeed.

However, theerror-related variables passed to the subroutines in my actualcode(a derived type with several strings and integer error codes, and an error-handling subroutine) are more complicated and bigger than in the example I submitted. Would this extra size/complexity add to the overhead?
Or, since all arguments are passed by address, maybe the only thing that matters is the actual number of arguments to the computational subroutine?

Thanks,

Olivier
0 Kudos
TimP
Honored Contributor III
1,515 Views
Interprocedural Optimization (IPO) is available to give the compiler the possibility of short-cutting argument passing overhead. Cases I have seen where the number of arguments became a performance problem involved many more arguments than this. It's not easily predictable by looking at source code, but it involved overflowing the number of cache line fill buffers available in the hardware. All current hardware products can handle at least 4 64-byte cache lines of these buffers per thread, so you would expect 16 addresses before choking when running in 64-bit mode, with less of a clear boundary in 32-bit mode.
0 Kudos
Jugoslav_Dujic
Valued Contributor II
1,515 Views
Quoting - opmkl
Or, since all arguments are passed by address, maybe the only thing that matters is the actual number of arguments to the computational subroutine?


Yes, that's the case. That means, in practice, that the overhead can be high only if you have a frequently-called, relatively short routine, with relatively high number of arguments.

For example, our computational library used to return the results to the caller through a callback routine, one element at the time, where the no. of elements was in the range of ~10,000-100,000. We discovered that such output processing takes almost as long as the computation itself, so we redesigned it to return the elements in arrays instead. That practically nullified the output time.

As the old computing law says, speed * memory * code_simplicity = const :-)
0 Kudos
OP1
New Contributor III
1,515 Views
Excellent - this is good news. Pretty much most of my subroutines carry these error-related variables and subroutine; I was concerned it was not the best practice and would slow down the code.

Thanks to all!

Olivier
0 Kudos
jimdempseyatthecove
Honored Contributor III
1,515 Views

Oliver,

Consider the following: Youhave a high iteration DO loop that calls a subroutine with it's arguments Plus the error message, error subroutine, other context (line number?, file name?, etc...). And the code in the subroutine is relatively small.

Under this circumstance it would be beneficial to remove the several extraneous arguments that will seldom be used.

What I suggest for this is to have an error stack (array to contain error context) in push/pop manner

[cpp]    call PushError(ERR_MSG, ERR_SUB, __FILE__, __LINE__)
    do i=beginHere, endHere
       call yourSub(a,b,c,d)
    end do
    call PopError()
    call YouCanStillDo(x,y,z,ERR_MSG, ERR_SUB, __FILE__, __LINE__)
[/cpp]


Jim Dempsey
0 Kudos
Reply