How Are Calculations Done for Variable That's Inclusive of Itself?
11 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Consider the following simple scenario:
x=x+1
In terms of computational efficiency and speed, I'm curious how this calculation is handled. x is inclusive of itself and overwriting itself with a new value. So I assume x has to first be moved to RAM to then complete the calculation and subsequently store the new value. I have a very large script, with large matrices, many loops, and lots of similar calculations. The script takes a long time to run and I'm wondering if this is a bottleneck that slows down the script. An alternative might be as follows, but I'm not sure if I'd gain anything.
temp=x
x=temp+1
In this latter case, x is not inclusive of itself in the calculation, so I wonder if this is more efficient.
I'd appreciate any input.
Thanks,
M Ridzon
3 commentaires
Greg
le 14 Déc 2017
Modifié(e) : Greg
le 14 Déc 2017
Sure can.
profile('on');
HW_5;
profile('off');
profile('viewer');
You'll get a nice-looking HTML report. Lots of options you can dig into, but it starts with a list of all functions called, and their respective run-times. Click the "HW_5' hyperlink and it'll show you line-by-line (with highlighting) run-times.
Réponses (2)
Greg
le 12 Déc 2017
Modifié(e) : Greg
le 12 Déc 2017
You won't gain anything with
temp = x;
x = temp + 1;
over
x = x + 1;
If you have a lot of loops and the code takes a long time to run, you may be having pre-allocation issues. We'd need to see your code to help with that. Otherwise, just do a MATLAB answers search for pre-allocation.
You can think of it simply that the copy of x to add 1 to itself costs you the same as copying x into temp, to add 1 to that. Either way, you still end up with 2 variables in memory (temporarily or permanently), and one copy of x happening.
10 commentaires
Walter Roberson
le 17 Déc 2017
We cannot tell from the timestamps at this point whether you or James last posted to that thread.
If it was you, then we can see that your question there was vague: just saying that you did not understand some of Jame's answer does not give us any hint about what aspects you did not understand.
I know that when I am answering questions, if someone posts and just says that my answer wasn't understandable and asks for other people to answer, without giving any information about what more is desired, then I might well not follow up, as such responses essentially tell me that my input on the topic is no longer welcome. And as someone looking in on a thread that someone else has been responding to, it is typically too frustrating to go through and break down the problem a completely different way when I have no idea what it was that was not understood in what the other person said; there is entirely too much chance that I would be wasting my time.
The volunteers thrive on specific questions, not on "I don't understand you; someone else please answer".
Walter Roberson
le 14 Déc 2017
x = x + 1
"So I assume x has to first be moved to RAM to then complete the calculation and subsequently store the new value."
Unless you are using the fairly new "tall arrays", x will already be in RAM. The parser will look up x in the symbol table (if it does not already know where it is), and what type it is, and locate the plus() function applicable for the data type, and will call the appropriate plus(x,1) . In the case of double() that is a built-in routine.
The built-in routine will check the sizes and see that you are adding a scalar to an array. It will check the size of the array to decide how best to handle it. If the array is not big, it will call into an internal routine. The internal routine will construct an output variable of appropriate size, and will then do a straight-forward loop through doing the addition. For double() the addition will just involve using the built-in machine instructions to add values. The internal routine will return the constructed temporary output variable, and that will be returned from plus. The parser will then see that the output is to be assigned to x, and will decrease the usage count associated with the storage x has been using. If the usage count reaches 0, then the parser will return that old memory. The parser will then adjust symbol table associated with x to point to the new location and size (the parser does not assume that the '+' operation returns something the same size as the original.)
I said above, "if the array is not big". If it is sufficiently large, then the built in plus routine will call into a high performance multi-threaded library to do the addition of 1. Even though it might hardly seem worth the effort of calling a high-performance library, the fact that the addition of 1 will be done in parallel over sections of memory can speed things up, and also the high performance libraries know all the tricks about cache sizes and all the tricks about SIMD (Single Instruction Multiple Data) to be able to trigger several additions with the same instruction. But there is overhead to going through all that trouble, which is why the library is only invoked if the array is large enough.
There are some performance tricks. There is a special case for functions of the form
function variable = function_name(variable, ...)
where the same variable is passed in and is written to, and the user calls the function writing to the same variable that the user passes in, and the variable has not been copied since it was last assigned to. In that particular case, MATLAB knows that it can re-use the memory -- so a function call
x = plus1(x)
function x = plus1(x)
x = x + 1;
has the potential for higher performance than a plain x = x + 1 . It is an obscure case.
3 commentaires
James Tursa
le 14 Déc 2017
Note that one additional requirement for the inplace operation of x=x+1 is that this line
x = plus1(x)
needs to be inside of a function itself.
Greg
le 16 Déc 2017
For kicks, I tried gathering actual execution time metrics on these 2 cases. I'm not sure if I'm implementing the "obscure case" correctly, but my results are negligible.
I tried with x = 1:1e9 (nearly an 8GB variable in RAM), and with passing that into the parent function as well as declaring it inside before calling plus1(x). The largest execution time delta I saw between using the plus1 function and not was 10%, and that was actually with plus1 being slower.
Voir également
Catégories
En savoir plus sur Code Execution dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!