| View previous topic :: View next topic |
| Author |
Message |
Polynomial Grandmaster Cheater
Reputation: 5
Joined: 17 Feb 2008 Posts: 524 Location: Inside the Intel CET shadow stack
|
Posted: Fri Aug 21, 2009 6:40 am Post subject: Optimisation of function |
|
|
Here's a quick bit of C++ code that I'm trying to optimise. It is being called repeatedly as part of a primality check test, and I'm trying to get this bit to run as fast as possible. I'm actually hoping that one of you will be able to come along and give me some crazy inline ASM that'll do this very quickly.
I'm assuming that combining the n%2 and n%3 lines will save a conditional jump (therefore increasing speed), but will this be negated by the fact that both n%2 and n%3 will need to be calculated every time?
| Code: | if(n < 4) return true;
if(n % 2 == 0) return false;
if(n % 3 == 0) return false;
if((n - 1) % 6 != 0 && (n + 1) % 6 != 0) return false;
/* do stuff here */ |
_________________
It's not fun unless every exploit mitigation is enabled.
Please do not reply to my posts with LLM-generated slop; I consider it to be an insult to my time. |
|
| Back to top |
|
 |
sven3107 Expert Cheater
Reputation: 0
Joined: 04 Feb 2009 Posts: 118 Location: Belgium
|
Posted: Fri Aug 21, 2009 8:30 am Post subject: |
|
|
| First thing I would think of is a switch block... |
|
| Back to top |
|
 |
Polynomial Grandmaster Cheater
Reputation: 5
Joined: 17 Feb 2008 Posts: 524 Location: Inside the Intel CET shadow stack
|
Posted: Fri Aug 21, 2009 8:34 am Post subject: |
|
|
A switch block would be completely useless in this case. I'm doing 3 checks that return true/false, not one check that returns many values. _________________
It's not fun unless every exploit mitigation is enabled.
Please do not reply to my posts with LLM-generated slop; I consider it to be an insult to my time. |
|
| Back to top |
|
 |
smartz993 I post too much
Reputation: 2
Joined: 20 Jun 2006 Posts: 2013 Location: USA
|
Posted: Fri Aug 21, 2009 10:07 am Post subject: Re: Optimisation of function |
|
|
| Burningmace wrote: | Here's a quick bit of C++ code that I'm trying to optimise. It is being called repeatedly as part of a primality check test, and I'm trying to get this bit to run as fast as possible. I'm actually hoping that one of you will be able to come along and give me some crazy inline ASM that'll do this very quickly.
I'm assuming that combining the n%2 and n%3 lines will save a conditional jump (therefore increasing speed), but will this be negated by the fact that both n%2 and n%3 will need to be calculated every time?
| Code: | if(n < 4) return true;
if(n % 2 == 0) return false;
if(n % 3 == 0) return false;
if((n - 1) % 6 != 0 && (n + 1) % 6 != 0) return false;
/* do stuff here */ |
|
It wouldn't matter if you combined %2 and %3..look at the %6 lines, they are combined, but when its compiled, they will be separate.
| Code: | ; 12 : if(n < 4) return true;
cmp DWORD PTR _n$[ebp], 4
jge SHORT $LN4@wmain
mov eax, 1
jmp SHORT epilogue
$LN4@wmain:
; 13 : if(n % 2 == 0) return false;
mov eax, DWORD PTR _n$[ebp]
and eax, -2147483647 ; 80000001H
jns SHORT $LN7@wmain
dec eax
or eax, -2 ; fffffffeH
inc eax
$LN7@wmain:
test eax, eax
jne SHORT $LN3@wmain
xor eax, eax
jmp SHORT epilogue
$LN3@wmain:
; 14 : if(n % 3 == 0) return false;
mov eax, DWORD PTR _n$[ebp]
cdq
mov ecx, 3
idiv ecx
test edx, edx
jne SHORT $LN2@wmain
xor eax, eax
jmp SHORT epilogue
$LN2@wmain:
; 15 : if((n - 1) % 6 != 0 && (n + 1) % 6 != 0) return false;
mov eax, DWORD PTR _n$[ebp]
sub eax, 1
cdq
mov ecx, 6
idiv ecx
test edx, edx
je SHORT $LN1@wmain
mov eax, DWORD PTR _n$[ebp]
add eax, 1
cdq
mov ecx, 6
idiv ecx
test edx, edx
je SHORT $LN1@wmain
xor eax, eax
jmp SHORT epilogue
$LN1@wmain:
; 16 :
; 17 :
; 18 : return 0;
xor eax, eax
epilogue: |
|
|
| Back to top |
|
 |
Polynomial Grandmaster Cheater
Reputation: 5
Joined: 17 Feb 2008 Posts: 524 Location: Inside the Intel CET shadow stack
|
Posted: Fri Aug 21, 2009 1:06 pm Post subject: |
|
|
What about multiplication? I can stick all of my checks into one line like this:
| Code: | | if((((n - 1) % 6) || ((n + 1) % 6)) * (n % 2) * (n % 3) == 0) return false; |
Would this work out faster? _________________
It's not fun unless every exploit mitigation is enabled.
Please do not reply to my posts with LLM-generated slop; I consider it to be an insult to my time. |
|
| Back to top |
|
 |
Slugsnack Grandmaster Cheater Supreme
Reputation: 71
Joined: 24 Jan 2007 Posts: 1857
|
Posted: Fri Aug 21, 2009 1:35 pm Post subject: |
|
|
| no it evaluates them one by one and then if there is a match at any stage then it will jmp to a return 0 piece of code ( lazy evaluation ) |
|
| Back to top |
|
 |
Jani Grandmaster Cheater
Reputation: 2
Joined: 29 Dec 2006 Posts: 804
|
Posted: Fri Aug 21, 2009 1:51 pm Post subject: |
|
|
| Why not to test it yourself if one is faster? Just compile it, call it hella lot times and time the results. Do it N times until your statistical data base is large enough to draw any conclusions. |
|
| Back to top |
|
 |
Slugsnack Grandmaster Cheater Supreme
Reputation: 71
Joined: 24 Jan 2007 Posts: 1857
|
Posted: Fri Aug 21, 2009 2:02 pm Post subject: |
|
|
would be better to test clock cycles instead of time though. since smaller code can be faster when looped even if each loop alone would have been slower. example is if more of the looped code could be cached. whereas realistically that code would be executed once only so the caching would not occur to the extent it does
solution : time by clock cycles |
|
| Back to top |
|
 |
hcavolsdsadgadsg I'm a spammer
Reputation: 26
Joined: 11 Jun 2007 Posts: 5801
|
Posted: Fri Aug 21, 2009 10:50 pm Post subject: |
|
|
This is the dumbest thing to optimize ever.
You will never have a humanly noticeable difference unless you run them a couple trillion times, if even then.
I checked the dissassembly and you would be hard pressed to write anything better on your own. It optimized most of the divides into multiplications, etc, etc. Mashing everything into one if does nothing besides make shit unreadable, they have to be evaluated anyway.
This is already faster than you would ever need for a real time application... a couple billionth of a second isn't ever going to matter besides wasting your time. Don't get hung up on trivial crap like optimizing IF STATEMENTS. |
|
| Back to top |
|
 |
Bswap Newbie cheater
Reputation: 0
Joined: 18 Aug 2009 Posts: 21
|
Posted: Sat Aug 22, 2009 9:24 pm Post subject: re: |
|
|
Code optimisation can refer to either speed of execution or size of code... which are you after?
Here's a quick effort at optimising for size;
| Code: | @check1:
cmp [_n], 4 ; (n > 4)
jge @false
@check2:
;xor edx, edx ; (n % 2) = 0
cdq ; cdq = 1 byte, xor = 2 bytes
mov eax, _n
mov ecx, 2
div ecx
test edx, edx
jne @false
@check3:
mov eax, _n ; (n % 3) = 0
inc ecx
div ecx
test edx, edx
jne @false
@check4:
mov eax, _n ; (n - 1) % 6 != 0
push eax
dec eax
mov ecx, 6
div ecx
test edx, edx
pop eax
je @false
xor edx, edx ; (n + 1) % 6 != 0
cdq ; cdq = 1 byte, xor = 2 bytes
inc eax
div ecx
test edx, edx
je @false
;
; do stuff here
;
@false:
sub eax, eax |
Last edited by Bswap on Sun Aug 23, 2009 1:20 am; edited 1 time in total |
|
| Back to top |
|
 |
DoomsDay Grandmaster Cheater
Reputation: 0
Joined: 06 Jan 2007 Posts: 768 Location: %HomePath%
|
Posted: Sun Aug 23, 2009 12:23 am Post subject: |
|
|
Tell me if I'm wrong:
Pick any random R, and then compute N = R * 6.
N+0: Would fail because {(N+0) % 2 == 0}
N+1: Would process because {(N+1-1) % 6 == 0}
N+2: Would fail because {(N+2) % 2 == 0}
N+3: Would fail because {(N+3) % 3 == 0}
N+4: Would fail because {(N+4) % 2 == 0}
N+5: Would process because {(N+5+1) % 6 == 0}
N+6: == (R+1) * 6 | Code: | mov eax,dword ptr [n]
cmp eax,4
jl _true
mov ecx,6
xor edx,edx
div ecx
cmp edx,1
je _process
cmp edx,5
jne _false
_process:
;do stuff here
jmp _end
_false:
xor eax,eax
jmp _end
_true:
xor eax,eax
inc eax
_end:
ret | On a side not, unless you're dealing with random values, you can also skip the comparison to 4 |
|
| Back to top |
|
 |
Polynomial Grandmaster Cheater
Reputation: 5
Joined: 17 Feb 2008 Posts: 524 Location: Inside the Intel CET shadow stack
|
Posted: Sun Aug 23, 2009 2:51 pm Post subject: |
|
|
I'm optimising for speed.
I'll give these a try and see what happens. _________________
It's not fun unless every exploit mitigation is enabled.
Please do not reply to my posts with LLM-generated slop; I consider it to be an insult to my time. |
|
| Back to top |
|
 |
Deltron Z Expert Cheater
Reputation: 1
Joined: 14 Jun 2009 Posts: 164
|
Posted: Mon Aug 24, 2009 8:48 am Post subject: |
|
|
If you need a list of primes you could use Sieve of Eratosthenes and then Binary Search on that list. faster, however takes up more space. it is useful when you need to check a lot of numbers a few times, instead of checking the same number a few times.
But as slovach said, you won't see any difference unless you execute this function millions or of times. |
|
| Back to top |
|
 |
|