I was thinking this morning here, what would be the fastest way to reverse a number of positive to negative and from negative to positive, of course, the simplest way might be:
int a = 10; a = a*(-1);
or
int a = 10; a = -a;
But then, I thought, I take that to do this, using commands shift and pointers ... That really would be possible to change the sign of a value, using commands shift operators and memory?
Negative numbers can be thought of as resulting from the subtraction of a larger number from a smaller. For example, negative three is the result of subtracting three from zero: 0 − 3 = −3.
function transform(a_begin, a_end, a1_begin, negate()): a_begin = lower bound of the array. a_end = upper bound of the array. a1_end = Lower bound of the second modified array. negate() = to negate the values of the array.
Use something that is readable, such as
a *= -1;
or
a = -a;
Leave the rest to the optimizer.
With optimization disabled, gcc for x86 compiles the first to this asm:
.file "optimum.c" .def ___main; .scl 2; .type 32; .endef .text .globl _main .def _main; .scl 2; .type 32; .endef _main: pushl %ebp movl %esp, %ebp andl $-16, %esp subl $16, %esp call ___main # MinGW library init function movl $10, 12(%esp) ;i = 10 negl 12(%esp) ;i = -i movl $0, %eax leave ret
With optimization disabled, the second one produces:
.file "optimum.c" .def ___main; .scl 2; .type 32; .endef .text .globl _main .def _main; .scl 2; .type 32; .endef _main: pushl %ebp movl %esp, %ebp andl $-16, %esp subl $16, %esp call ___main movl $10, 12(%esp) ;i = 10 negl 12(%esp) ;i = -i movl $0, %eax leave ret
Same output! No difference in the assembly code produced.
--------------------------EDIT, OP ANSWERS HE USES VC++2012, INTEL ARCH-------------------
Compiled using cl optimum.c /Fa optimum.asm
(optimization disabled)
; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.30319.01 TITLE C:\Users\Dell\Downloads\TTH\TTH\TTH\optimum.c .686P .XMM include listing.inc .model flat INCLUDELIB LIBCMT INCLUDELIB OLDNAMES PUBLIC _main ; Function compile flags: /Odtp _TEXT SEGMENT _a$ = -4 ; size = 4 _argc$ = 8 ; size = 4 _argv$ = 12 ; size = 4 _main PROC ; File c:\users\dell\downloads\tth\tth\tth\optimum.c ; Line 4 push ebp mov ebp, esp push ecx ; Line 5 mov DWORD PTR _a$[ebp], 10 ; 0000000aH ; Line 6 mov eax, DWORD PTR _a$[ebp] neg eax ;1 machine cycle! mov DWORD PTR _a$[ebp], eax ; Line 7 xor eax, eax ; Line 8 mov esp, ebp pop ebp ret 0 _main ENDP _TEXT ENDS END
and with second approach (a = a * -1
), optimization disabled MSVC:
; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.30319.01 TITLE C:\Users\Dell\Downloads\TTH\TTH\TTH\optimum.c .686P .XMM include listing.inc .model flat INCLUDELIB LIBCMT INCLUDELIB OLDNAMES PUBLIC _main ; Function compile flags: /Odtp _TEXT SEGMENT _a$ = -4 ; size = 4 _argc$ = 8 ; size = 4 _argv$ = 12 ; size = 4 _main PROC ; File c:\users\dell\downloads\tth\tth\tth\optimum.c ; Line 4 push ebp mov ebp, esp push ecx ; Line 5 mov DWORD PTR _a$[ebp], 10 ; 0000000aH ; Line 6 mov eax, DWORD PTR _a$[ebp] imul eax, -1 ;1 instruction, 3 machine/cycles :| mov DWORD PTR _a$[ebp], eax ; Line 7 xor eax, eax ; Line 8 mov esp, ebp pop ebp ret 0 _main ENDP _TEXT ENDS END
So if you care about the performance of your debug-mode asm under MSVC, you could optimize your source accordingly. Normally you only care about performance in optimized builds.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With