How Are Calculations Done for Variable That's Inclusive of Itself?
Mostra commenti meno recenti
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 Commenti
Greg
il 12 Dic 2017
Run your code inside the profiler to see exactly which line (or lines) causes the slowdown.
Matthew
il 12 Dic 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.
Risposte (2)
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 Commenti
Matthew
il 12 Dic 2017
Greg
il 14 Dic 2017
I have one guiding principle: teach as much as the student is willing to learn. If you care to get better, I'll care to help you (conversely, if you don't care, that's cool but I won't waste my time). If you'd like, I see your profile lets me contact you through email, I can (as I have time) give some pointers after looking through your attached code.
Matthew
il 14 Dic 2017
Greg
il 14 Dic 2017
@Matthew: Your observation is spot on. But here's a little background to put it in context. We (the common answerers) have all been burned by a questioner that just didn't care. After the first time you spend an hour crafting an amazing response (see Walter Roberson's answer here) and the person asking the question declines it, or deletes the question entirely, you stop putting in the effort up front.
Also, the activity feed is relatively new, and boy is it handy for staying connected to previous efforts. Hopefully some of us start reducing our "drop it and move on" behavior.
Image Analyst
il 14 Dic 2017
Matthew, overall the code is not bad. It has two things I like to see: (1) fairly well commented code (though it never hurts to add more), and (2) descriptive variable names. I insist on those two things when people write code for me. No one likes to look at a long, uncommented alphabet soup of code. It's impossible to follow, maintain, understand, or inherit from someone. One suggestion I'd have, though it's a matter of style, is to use more spaces around things, like after commas and around relational and mathematical operations (+ - <=, etc.)
John D'Errico
il 16 Dic 2017
In response to Matthew, upset that some won't respond to a followup.
I would point out that many times, someone asks a question about problem X. Having gotten help on that point, they then ask a second, unrelated question in the comments. If they got an answer to that question, they would then continue asking unrelated followup questions, making one question into their own personal consulting forum.
Note that those who do actively answer questions may answer dozens or even hundreds of questions in a week. Each such answer may take a few minutes to write, and for some of us, well over an hour, or more. If an answer was complete as posted, then once one sees needy followups start to appear, it becomes time to stop responding.
Matthew
il 16 Dic 2017
Walter Roberson
il 16 Dic 2017
Matthew, I went back over all of your Questions. In most of them, the volunteers are the last contributors to the question, so if you wanted more response then you should have said something. Most of the Questions in which you were the last contributor were cases in which you were thanking people for having solved the problem. We have to go back to November 2015 to find something that wasn't solved for you, when you asked about Blauhus conditions. We have to go back to November 2014 to find a case where you had asked a follow-up that was not replied to.
Matthew
il 17 Dic 2017
Modificato: Walter Roberson
il 17 Dic 2017
Walter Roberson
il 17 Dic 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
il 14 Dic 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 Commenti
Matthew
il 14 Dic 2017
James Tursa
il 14 Dic 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
il 16 Dic 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.
Categorie
Scopri di più su Spline Postprocessing in Centro assistenza e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!