![]() |
goto thread wentto here
in root_score.c for poly selection I was wondering why you used 65000 for 2^16? Its probably not a problem or bottleneck, but I rewrote the section to what I thought might be better...
[code] /* find the largest power of p that does not exceed 2^16 */ max_power = 1; power = p; while (1) { uint32 next_power = power * p; if (next_power > 65000) break; power = next_power; max_power++; } [/code] ^original^, mine is below. [code] /* find the largest power of p that does not exceed 2^16 */ max_power = 1; power = p; uint32 next_power = power * p; while (next_power <= ushort.maxvalue) { //works in c# don't know about c max_power++; power = next_power; next_power *= p; } [/code] Also in stage1_roots.c I was wondering where #define SIEVE_SIZE 16384 comes from, shouldn't it depend on the cache size of the cpu? |
[QUOTE=Joshua2;168075]in root_score.c for poly selection I was wondering why you used 65000 for 2^16? Its probably not a problem or bottleneck, but I rewrote the section to what I thought might be better...
[/QUOTE] No improvement, because there is no perfect prime power in the (65000,65536) interval. |
[QUOTE=R. Gerbicz;168078]No improvement, because there is no perfect prime power in the (65000,65536) interval.[/QUOTE]
Ok, but I learned in programming class to avoid using break statements when possible. Since there are only a few primes, it seems they could be hard-coded, but that probably wouldn't save much time. |
[QUOTE=R. Gerbicz;168078]No improvement, because there is no perfect prime power in the (65000,65536) interval.[/QUOTE]
But is that relevant? The point of the loop is to multiply by p for as many times as possible. You don't need to multiply by p if your current result exceeds 2^16/p which to satisfy all cases means 2^16/2=2^15=32768. The loop is therefore perfectly correct when 65000 is replaced by 32768. This actually only saves at most one multiply for a single case so unless this loop is in heavy use, there's no real gain. A sample satisfying Joshua2's "avoid break's and goto's" principle (and not a principle I blindly adhere to I might add, especially where performance is important): [CODE]/* find the largest power of p that does not exceed 2^16 */ max_power=1; power=p; while (power<=SHRT_MAX && (next_power=p*power)<=USHRT_MAX) { power=next_power; max_power++; } [/CODE] |
Doesn't that have twice as many comparisons as necessary? When will "(next_power=p*power)<=USHRT_MAX)" be true and "power<=SHRT_MAX" be false?
|
[quote=FactorEyes;168113]Huh. I thought you were younger than that.[/quote]
"On the internet, nobody knows that you are a dog." <== Is that better? Social mimicry was good for a while. Now it's time to reveal my real self. "avoid break's and goto's" principle is good for beginners. It is very true that this how most programmers should be taught. Then, if/when they get to the next level, they will be told (or they will tell themselves) that all has to be forgotten and learned from scratch. The serious debate would be long (I mean it is long, tons of stuff can be found about it), so let's just leave it at that. Look at the lasieve code. Shocking! Not just gotos, but setjmp's are used. How amateurish! (Of course not.) Same with physics. Many times, students will hear: "forget all you've learned in the last class and all classes before." ...but those who didn't get into this class will in fact do better with [I]that other, easy[/I] physics that they learned earlier. Same with chess. First class: queen moves like this, rook moves like that, and never put you pieces under attack. It would be silly to analyze Alekhin-Capablanca or whatever in the first class; "why did he put his queen here? it's under attack" questions will follow. Or more closer to this example, why did he move like that - right here, in this move? makes no sense! ...because he was concentraing on the attack to follow in ten moves, and this paricular move upon consideration had no significance at all - so don't drill into it. He spent no time thinking about this move, and one day, so will you. (Alas, I never will. I am hopeless here.) Very few parts of the code need all optimization you can get (including unimaginable), and the bulk don't and should be readable, that's all. My 2 cents. |
I remember hearing a quote somewhere, but don't remember the source. It went something like: "Mastering an art takes twenty years. Ten years to learn all the rules, then another ten to learn when to break them."
Alex |
[QUOTE=Batalov;168181]"avoid break's and goto's" principle is good for beginners. It is very true that this how most programmers should be taught. Then, if/when they get to the next level, they will be told (or they will tell themselves) that all has to be forgotten and learned from scratch. The serious debate would be long (I mean it is long, tons of stuff can be found about it), so let's just leave it at that.[/QUOTE]
Why should programmers be taught to avoid "break"s? You would have difficulty trying to code a switch statement without them. I could understand the "continue" statement. I've known a lot of programmers who are confused by it. Personally I'm not a fan of "goto"s in C code. IMO, well-designed code shouldn't need them. Where I work there is a project that requires all functions to have a single exit point, thus gotos are required to make that happen, but the only reason for the single exit point is a trace statement before returning. IMO, it should be quite acceptable to use return from within a function to reduce the need for unnecessary if statements. I'm certain that many of us have seen 10 or more nested ifs in a single function. Combine that with a poor use of white space makes code difficult to read. One thing that does annoy me a little is the use of "int" in code that is intended to be compiled across multiple platforms where the size varies from platform to platform. I often find that developers who presume that an int is always 32 bits only to find that code breaks on platforms where it is 16 bits. I prefer using the defines in stdint.h to help avoid these issues. It also helps avoid some issues that might occur when using a 32-bit or 64-bit compiler switch. The code should work correctly regardless of the switch used. |
[quote=rogue;168184]Why should programmers be taught to avoid "break"s? You would have difficulty trying to code a switch statement without them.[/quote]
Indeed, and even in the case of loop statements, it's quite silly to avoid break statements. Personally, I would gladly go the other way and make an explicit break the [I]only[/I] way to exit a loop. [quote=rogue;168184]Where I work there is a project that requires all functions to have a single exit point, thus gotos are required to make that happen, but the only reason for the single exit point is a trace statement before returning.[/quote] Well that's just stupid. Each function should be divided into two, with the outer function just calling the inner one and doing the tracing, and the inner returning to the outer one wherever necessary; also, the outer functions should be invocations of a macro or a template. |
[quote=Joshua2;168083]Ok, but I learned in programming class to avoid using break statements when possible.[/quote]
So, I assumed that it was taught this way, then... I like this opinion: [URL="http://portal.acm.org/citation.cfm?id=203373"]C in the first course considered harmful[/URL] |
[QUOTE=Joshua2;168170]Doesn't that have twice as many comparisons as necessary? When will "(next_power=p*power)<=USHRT_MAX)" be true and "power<=SHRT_MAX" be false?[/QUOTE]
No. The first inequality is the early exit, saving 1 multiply (not a big savings), the second inequality only gets invoked if the first inequality is true - that's how C evaluates AND expressions. In the C language the scenario you suggested will never be evaluated, so all of the primes above USHRT_MAX will exit the loop without having to do the trial multiply by p. |
| All times are UTC. The time now is 04:55. |
Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.