Cost of using functions in fortran (or any other language) - fortran

Let say I have a array which is very big verybigvariable
And I have defined a function that does some operations like this
function myfunc(var) result(res)
real:: var(:,:,:),res
...
...
...
end function myfunc
My question is that when I call this function like this
myvar=myfunc(verybigvariable)
what happens? does it duplicate my variable so it holds 2X space in the ram during the execution of the function? If so how can I prevent this? (In a simple program, I know, I can define the function without any parameter and make it use existing variables, but If I am programming a module, it seems I have to include parameter to the definition)

The Fortran language standard does not specify how arguments are passed. Typically in the interest of efficiency the compiler will not make a copy but pass the address of the argument. There will be cases in which a Fortran compiler has to make a copy. E.g., the actual argument is a non-contiguous array but the procedure expects a contiguous argument. The compiler will have to fix the mismatch by making a copy that is contiguous to pass to the procedure. If the procedure modifies that argument, the values have to be copied back to the original argument.

In fortran it seems that parameters are passed by reference. This means that only the address of the variable is passed, and the function can then access the variable through that address.
So no, the array is not copied, only the address of the array is passed. The overhead for this will be either 32 bits for a 32-bit system, or 64 bits for a 64-bit system.
I have no experience with fortran, and this is only what I could figure out though a Google search, so if any Fortran programmers have any remarks, please feel free to edit/comment.

Related

Faster way to call a method in c++

Quick question and I apologize if it sounds naive.
What is faster in c++. A code like this:
ProgramsManager::CurrentProgram->Uniforms->Set(n1);
ProgramsManager::CurrentProgram->Uniforms->Set(n2);
ProgramsManager::CurrentProgram->Uniforms->Set(n3);
ProgramsManager::CurrentProgram->Uniforms->Set(...);
Or this one?
Uniforms* u = ProgramsManager::CurrentProgram->Uniforms;
u->Set(n1);
u->Set(n2);
u->Set(n3);
u->Set(...);
I know the second piece of code is faster in interpreted languages, but I feel like it makes no difference in compiled languages. Am I right?
Thank you in advance
The second might be faster, but it won't be faster by a lot.
The reason it might be faster is if the compiler cannot prove to itself that ProgramsManager::CurrentProgram->Uniforms could be changed by the calls to ...->Set. If it can't prove this, it will have to re-evaluate the expression ProgramsManager::CurrentProgram->Uniforms for each line.
However, modern CPUs are usually fairly quick at this kind of thing, and compilers are getting better.
There are 3 choices here, not 2.
Call a single parameter function.
Call one function with many parameters.
Call a single function with container, like struct or vector.
Fundamental Overhead
When calling a function there is an overhead of instructions. Usually this involves placing values in registers or on the stack or something else.
Lower level, there may be the possibility of the processor having to reload it's instruction cache / pipe line.
Optimizing The Function Call
For optimizing function calls, the best method is to avoid the call by pasting the code (a.k.a. inlining). This removes the overhead.
The next best is to reduce the number of function calls. For example, passing more parameters will use less function calls and less overhead.
Many Parameters versus One Container
The optimal function call passes values by registers. Extra parameters, more than the available registers, results in using the stack memory. This means that the function will need code to retrieve the values from the stack memory.
Passing many parameters using the stack incurs an overhead. Also, the function signature will need to change if more parameters are added or removed.
Placing variables into a container reduces the overhead. Only a pointer (or reference) to the container needs to be passed. This usually involves only a register since pointers usually fit into a register (many compilers pass structures by reference using pointers).
Another benefit to the container is that the container can change without having to change the function signature.

Accessing global array more efficient than passing as argument?

I have a function which is called many times and I need to pass an array of 4 or 5 elements down in to 3 or 4 nested functions.
Surely it would be more efficient to create this array data structure as a global variable where all functions can access it with one address reference, rather than passing it down the nested functions as an argument. The latter would require stack pushing and popping whereas the global variable wouldn't?
(I know I can profile, but I want to understand what the theory would suggest- the difference in what code would be executed)
1-first of all an array in C/C++ is just a contiguous area reserved in memory , with a pointer to the first element namely : Arr[0]
2-passing array as a parameter most likely consumes a register in parameter passing (according to calling convention used and count of function parameters)
while using a global variable will not consume this register
3-to the compiler passing the parameter like
a) Foo(int* Arr)
b) Foo(int Arr[])
is just the same, a pointer is copied to the register or the stack according to calling convention used
the format in (b) may just give a hint to the compiler that there are no overlapping while processing the array to make better optimization
You can use pointer or reference instead of passing whole array.
If it is C plus plus, make that array member variable.

is it possible to use function pointers this way?

This is something that recently crossed my mind, quoting from wikipedia: "To initialize a function pointer, you must give it the address of a function in your program."
So, I can't make it point to an arbitrary memory address but what if i overwrite the memory at the address of the function with a piece of data the same size as before and than invoke it via pointer ? If such data corresponds to an actual function and the two functions have matching signatures the latter should be invoked instead of the first.
Is it theoretically possible ?
I apologize if this is impossible due to some very obvious reason that i should be aware of.
If you're writing something like a JIT, which generates native code on the fly, then yes you could do all of those things.
However, in order to generate native code you obviously need to know some implementation details of the system you're on, including how its function pointers work and what special measures need to be taken for executable code. For one example, on some systems after modifying memory containing code you need to flush the instruction cache before you can safely execute the new code. You can't do any of this portably using standard C or C++.
You might find when you come to overwrite the function, that you can only do it for functions that your program generated at runtime. Functions that are part of the running executable are liable to be marked write-protected by the OS.
The issue you may run into is the Data Execution Prevention. It tries to keep you from executing data as code or allowing code to be written to like data. You can turn it off on Windows. Some compilers/oses may also place code into const-like sections of memory that the OS/hardware protect. The standard says nothing about what should or should not work when you write an array of bytes to a memory location and then call a function that includes jmping to that location. It's all dependent on your hardware and your OS.
While the standard does not provide any guarantees as of what would happen if you make a function pointer that does not refer to a function, in real life and in your particular implementation and knowing the platform you may be able to do that with raw data.
I have seen example programs that created a char array with the appropriate binary code and have it execute by doing careful casting of pointers. So in practice, and in a non-portable way you can achieve that behavior.
It is possible, with caveats given in other answers. You definitely do not want to overwrite memory at some existing function's address with custom code, though. Not only is typically executable memory not writeable, but you have no guarantees as to how the compiler might have used that code. For all you know, the code may be shared by many functions that you think you're not modifying.
So, what you need to do is:
Allocate one or more memory pages from the system.
Write your custom machine code into them.
Mark the pages as non-writable and executable.
Run the code, and there's two ways of doing it:
Cast the address of the pages you got in #1 to a function pointer, and call the pointer.
Execute the code in another thread. You're passing the pointer to code directly to a system API or framework function that starts the thread.
Your question is confusingly worded.
You can reassign function pointers and you can assign them to null. Same with member pointers. Unless you declare them const, you can reassign them and yes the new function will be called instead. You can also assign them to null. The signatures must match exactly. Use std::function instead.
You cannot "overwrite the memory at the address of a function". You probably can indeed do it some way, but just do not. You're writing into your program code and are likely to screw it up badly.

Direct the compiler how to optimize my code

How I can say to the compiler how to optimize something or what some call to function.
I mean like create allocate method and let the compiler optimize it as it optimize it with malloc or new.
Or like if somewhere in the code the function X is called and it's return value is not used then delete this call. (Function from .lib that the compiler don't know a piece about it)
There are options for this?
For example:
auto val=X(); //Use the return value
X(); //Don't use
auto t=allocate<T>(); //Allocate on heap
t->Show(val); //Run single function and don't use it's pointer somewhere (Save it after the function is exit)
And optimize it to:
X(); //First line, just call it
T().Show(val); //Combines third and fourth lines, Allocate on stack and run the single function
If you asking 'why you need this?' I am creating programming language with my own GC and heap. (And lot of things too)
It translates to C++ then I don't want to optimize the code while translate it. (It's gonna be a pain)
Because I can call functions randomly in places. (I can't detect if their values are used or not)
Optimization is compiler-specific, so you'll need to look in your compiler's documentation to see what optimization "hints" it allows you to put in code. For example, here are some of GCC's function attributes:
The malloc attribute tells the compiler that if the function returns a non-null pointer, it's always a "new" area of memory, not another pointer to something that's already been allocated. You'd probably want to use this on a function that wraps the real malloc().
The const attribute (different from the ordinary const keyword) says that the function's return value depends solely on its arguments and has no side effects, so it's safe for the compiler to eliminate duplicate calls with the same arguments.
The noreturn attribute tells the compiler that a function never returns; you'd use this on functions that terminate the program, like C's exit().
Attributes go on the declaration of a function, typically in a header file, so you can use them even if the function's implementation is in a compiled library that'll be linked in later. But remember that function attributes are promises from you to the compiler: if you declare a function with the noreturn attribute, for example, and then implement it with code that actually can return, strange things may happen at runtime when it does.
You can also use function attributes to help with correctness checking:
The nonnull attribute tells the compiler that certain (pointer) arguments aren't supposed to be null, so it can issue warnings if it detects that they might be.
The format argument tells the compiler that the function takes a format string like C's printf(), so it can check that the types of the variadic arguments match the corresponding format codes in the format string. (For example, you shouldn't write "%s" in the format string but then pass an integer as its value.)

Reg function pointer

I have one clarification
What is the difference between calling a function through function pointer and calling a function directly by name ?
Anybody help me in this.
There is no difference in the actual call. Parameters are passed the same way, the function runs the same way, and the return value comes back the same way.
The only difference is that you can make the function pointer point somewhere else.
There is no difference except that a compiler/linker calculates exactly what address to transfer control of the program to when you call a function by name and hardcodes that value into the code, whereas with function pointers, the computer must use the pointer to calculate where to transfer control to at runtime.
No difference (except that calling by name will always call the same function, and pointer can be changed to point to different functions).
While the direct use of function pointers does not have any cost, you should bear in mind that function pointers aren't compile time constants, so it maybe has a cost to read them. So if you have a function pointer inside a class and use that to emulate polymorphic behavior, you won't get any speedup at all.