Talk:NOP

From Wikipedia, the free encyclopedia

Note: NOOP Protocol Commands section is based off a section I wrote, original article noop. --Rgb9000

Contents

[edit] i++ statement

The i++ statement does have a net effect- therefore making it a bad candidate for an example of NOOP. This has been replaced with i + 1; which does not change any values in memory, and simply returns its value into nothingness.

Indeed it does, but here it was followed by i--, which means that there is no net effect unless there's something weird going on in the background that I don't know about. --Aurochs
No, the person above is absolutely right. Either operation, i++ or ++i will affect the value of i! These are not the same as a NOOP, this are the same as "INC i" where INC would be an increment operator in the CPU. Like you said in your edit comment, i+1 effectively does nothing. (Actually, without optimization, it LOADS the value of i into a register, increments it by one, and then forgets about the value. Optimizing compilers see this, ignore the operation, and replace it with a NOOP.) i+1 is STILL valid c++! Much in the same way i=j=k=m+1 is! Try it! You'll see that it will compile and everything. More to the point, if i have a function int dosomething(), i can just call dosomething() and ignore the return value because c/c++ allows this for all functions. i+1 is such a function.--Stux 15:33, 9 November 2005 (UTC)
I think you're missing the point. The following code:
i++;
i--;

has no net effect. It incerments i and then immediately decrements it, so i has returned to its original value and there was no intervening code to use the incermented variable. It is effectively an nop, though the amount of time it takes to execute differs from your i + 1 example. --Aurochs
Oh! My apologies! Now I understand what the example was saying! At first I thought (and I'm sure the user that originally changed the i++ to an i+1 probably thought as well), that the example was listing two individual statements. Upon more careful reading (of the text and of your comments) I realized now what it meant. Since it seemed rather easy for passers-by to misinterpret that example (much in the same way I did), I changed the example back to the original, but added brackets and wording to make it clear that it is meant to be understood as one group of instructions. I also added the i+1 example back in as an alternative. If you feel the wording needs to be improved, please do so! Again, thanks for pointing out the error. (Thank you for your politeness and understanding as well! It seems nowadays that is lacking from the users of this wiki.) --Stux 22:08, 9 November 2005 (UTC)
I'm going to remove this example. As i++; i--; changes values in memory, it's not really a no-op. (I realize the probability is unlikely, but what happens if another thread raises an exception before i--; gets called? - Chardish 16:11, 6 December 2006 (UTC)
No, i++; i--; is not a NOP. Let's assume the compiler translates it to this pseudo-assembly code:
1: INC i
2: DEC i
On most (all?) CPUs, these two instructions are not atomic. Let's assume the program containing this code is running two threads and a context switch occurs between instructions 1 and 2. The value of i is now one more than the original value. If the second thread attempts to read i at it point, it will read the wrong value. — 71.155.235.243 00:39, 31 March 2006 (UTC)
i++; i-- can cause an overflow trap depending on the type of i. An unsigned int will never trap, but a plain (signed) int or a float may do so. If adding the declaration is deemed too distracting, I suggest changing the example to i += 4711 * 0 or similar. Kjetilho 07:51, 4 October 2006 (UTC)

[edit] NOPs that aren't really

I think that this article should cover the fact that not all processors have an opcode that is truly set aside as a NOP. The most obvious example is the x86. Opcode 90 really means "xchg eax, eax". MIPS's NOP is really "sllv zero, zero, zero" if I remember right.

Of course, this can change over time. When the x86 became pipelined, "nop" stopped being "xchg eax, eax". It's special cased for performance reasons; "xchg" is a somewhat expensive instruction. Also, "xchg eax, eax" implies to the instruction scheduler that the instruction depends on the previous value of EAX.

x86-64 further differentiates it. "xchg eax, eax" actually does something - it now truncates RAX to 32 bits, as in "movzx rax, eax". Assemblers don't encode "xchg eax, eax" as 90. -- 68.228.65.220 06:48, 10 October 2006 (UTC)

[edit] Optimising compilers

I recently added the following text to the NOP code section:

Note that in code which is compiled using an optimizing compiler, it is likely that any such redundant statements will be removed before they get a chance to be executed.

It was removed with the edit comment "There are no redundant statements in the example given". Perhaps the intent of this sentence was not clear, so I'll explain it here and perhaps we can work out a better way of putting it. My point is that in a non-optimising compiler, the given instructions may well be compiled into the binary (e.g. the source code i + 1; might result in machine code that performs an ADD and discards the results), but in an optimising compiler the whole instruction will be recognised as redundant and removed. Therefore in an optimising compiler, main() { } and main { int i; i+1; } should produce exactly the same binary code. --HappyDog 08:54, 23 May 2007 (UTC)

  • Firstly compiler optimization is a continuum, all that can be said is optimizing compilers do more optimizations than non-optimizing compilers. In the context of the code fragment it was not clear that that optimization of dead code was being discussed. But my main point is that this article is about NOP, not compilers removing unnecessary code. Ok, unnecessary code may be regarded as effectively a nop, but that is a rather indirect connection for an article like this to make. Derek farn 10:59, 23 May 2007 (UTC)
That's all true, but reading that section, the implication is that the example code will compile into NOP instructions. The paragraph begins An example of a single C statement that would also produce a NOP:, which is not true in optimising compilers that (as you rightly qualified) detect this kind of redundancy. However, as this is such a basic optimisation to make, I would suspect (based on no actual research :-)) that most such compilers would manage this. Perhaps the introduction to this section needs rewording, because it is unclear whether you are saying that this kind of instruction is called a NOP by C programmers (which in my experience it never is - 'void' is a more common term, if anything) or whether it compiles to a NOP, in which case a note about optimising compilers is required, imho. --HappyDog 11:30, 24 May 2007 (UTC)
I recently added something to this effect, which was reverted. Two points. There is no compiler I'm aware of, which at any optimisation level, ever, added in NOPs for empty lines of C code. That just isn't how compilers work. Why would they want to put in the extra work to output a NOP, when instead they could simply output nothing? Just because a compiler doesn't optimise well, doesn't mean it goes around purposefully spending extra work slowing things down. I think we do need a line which says that the NOPs of code are not directly related to NOPs of assembler itself, as too many people (including some people here, no offense), think that C compilers might output NOPs for empty instructions which isn't true at any optimisation level Mrjeff 09:55, 7 June 2007 (UTC)
For some architectures, a compiler will generate a NOP for some occurrences of a null statement. For instance, it may be necessary to fill the delay slot of a branch instruction on a MIPS processor. This is a rather unusual edge case and mentioning it will only complicate the issue. Do people actually think that in normal operation, a compiler goes round purposely generating NOPs when it detects redundant code?. Derek farn 10:40, 7 June 2007 (UTC)
In this instance the compiler is inserting its own NOPs where necessary. It still won't convert null statements into NOPs. --HappyDog 14:19, 7 June 2007 (UTC)

[edit] Behaviour/output.

The word 'behaviour' was changed to 'output' in this edit with the edit summary Behavior can include things other than output. However, surely the point of NOP is that it has no effect, whether to behaviour or output, so I am unsure why the change was made. Perhaps I misunderstand the purpose of the sentence. Can you explain what you are trying to say with it? --HappyDog 17:06, 27 May 2007 (UTC)

A construct considered to be a NOP can exhibit behavior if actual instructions are generated/executed. Time and power (electrical) will be consumed. Yes, this behavior will require sensitive equipment to detect, but it is still behavior. You are right in that it is a rather picky point. But in many cases the essence of a NOP is that it is often something that happens (in other cases nothing at all happens) that has no consequences at the human level (I use the term program output when perhaps "no external effect noticeable human level" might be technically more accurate, if somewhat long winded). Derek farn 19:33, 27 May 2007 (UTC)

[edit] Null statements and style

Another use of a null statement in C is for a goto label at the end of a block, e.g.:

if (a_condition)
{
    for (;;)
    {
        if (some_condition)
            goto endloop;
        ...
    }
endloop: ;
}

I should point out that using the continue statement is a better way to write empty loop bodies in C:

while (ReadChar() != '\n')
    continue;

Except for a few rare exceptions, the use of null statements is generally considered bad programming style, especially in languages like C where a single ";" character can be easily misplaced or overlooked. A more visible approach is to use an empty block:

if (condition_1)
{ }    // Do nothing
else if (condition_2)
    do_something();
else
    do_something_else();

Loadmaster 17:11, 30 May 2007 (UTC)

Let's not be C specific. Are there any kinds of NOP 'statements; that appear in other languages and perhaps are not found in C? Derek farn 17:30, 30 May 2007 (UTC)

[edit] Comments

Does a comment count as a NOP? --HappyDog 02:36, 31 May 2007 (UTC)

A comment is not intended to be an operation. A NOP is an instruction that looks like it might do something (of course it does, it wastes cpu time and takes up storage). Derek farn 11:15, 31 May 2007 (UTC)
A C compiler will discard a null statement and a comment in the same way - neither will be converted into executable code. Both are lines in the source code that do nothing. I don't quite see the distinction. --HappyDog 12:05, 31 May 2007 (UTC)
Perhaps I am being overly keen to create a distinction. I guess one definition of NOP is something that is not an operation (or a vegetable, or a rock, or a etc...) The usage I am familiar with is when a construct is normally an operation, but for some reason it is written in such a way that no operation actually takes place. Now this may just be splitting hairs, but to me a comment is obviously not a NOP. Perhaps somebody else can describe it better than me (or perhaps people do regard a comment as a NOP and I am just out of touch). Derek farn 15:38, 31 May 2007 (UTC)
I meant that a null statement in C is not something I would consider a NOP - I wasn't trying to imply that a comment was. My point was that in a compiled language the whole concept of a NOP is somewhat nebulous, and that in C the relationship between a null statement or a comment and the resulting source code is the same - they are both discarded by the compiler. Therefore defining a NOP in terms of the resulting machine code does not work. --HappyDog 23:37, 31 May 2007 (UTC)
Comments are known to execute very fast. ;-) — Loadmaster 23:35, 31 May 2007 (UTC)
I don't read the text as defining NOP in terms of the resulting machine code. I think it reads as being in terms of intent. Derek farn 10:33, 7 June 2007 (UTC)