digitalmars.D - Formal annotating Code for Optimizations?
- Manfred_Nowak (33/33) Jul 18 2008 Example:
- Craig Black (8/40) Jul 18 2008 It'll never be implemented, but it's a good idea. Along the same lines,...
- Walter Bright (7/12) Jul 18 2008 That optimization is not possible, because the compiler doesn't know if
- downs (39/39) Jul 18 2008 The following mixin code can be used to generate optimized code for spec...
- JAnderson (6/42) Jul 18 2008 MSVC++ 2005 has this profile that you can run on the code and then it
- Sean Kelly (5/44) Jul 18 2008 The Sun compiler does this too. It's the code rearranging that's the
- Walter Bright (4/8) Jul 18 2008 The dmd profiler does this too. It emits a file, trace.def, which
- BCS (2/13) Jul 18 2008 Oh? Cool! Link?
- Walter Bright (2/17) Jul 18 2008 http://www.digitalmars.com/ctg/trace.html
- bearophile (4/7) Jul 18 2008 Oh, good, so in the future you may do the last little step, adding to dm...
- JAnderson (4/13) Jul 18 2008 That's cool! It sums over multiple runs as well. I might leave it on
Example: If two actions `a1',`a2' are based on a binary decision `b' then on a pure logical level one can code: if( b) a1.do; // actions have `do'- and `undo'-methods else a2.do; But if one knows, that the probability of `b' to be `true' is much greater than .5, then in order to use the precomputing capabilities of the CPU one would probably like to code: a1.do; if( !b){ a1.undo; a2.do; } The other case requires similar code. In this latter code the abstraction of a simple binary decision seems to be less obvious, which seems to be bad for maintenance. Of course one can annotate with comments. But since comments can be hints for defencies in the language, the question rises whether one should formalize this: if( b)note( p(b)>.8) a1.do; undo a1.undo; else a2; undo a2.undo; -manfred -- Maybe some knowledge of some types of disagreeing and their relation can turn out to be useful: http://blog.createdebate.com/2008/04/07/writing-strong-arguments/
Jul 18 2008
"Manfred_Nowak" <svv1999 hotmail.com> wrote in message news:g5ptdk$2t8f$1 digitalmars.com...Example: If two actions `a1',`a2' are based on a binary decision `b' then on a pure logical level one can code: if( b) a1.do; // actions have `do'- and `undo'-methods else a2.do; But if one knows, that the probability of `b' to be `true' is much greater than .5, then in order to use the precomputing capabilities of the CPU one would probably like to code: a1.do; if( !b){ a1.undo; a2.do; } The other case requires similar code. In this latter code the abstraction of a simple binary decision seems to be less obvious, which seems to be bad for maintenance. Of course one can annotate with comments. But since comments can be hints for defencies in the language, the question rises whether one should formalize this: if( b)note( p(b)>.8) a1.do; undo a1.undo; else a2; undo a2.undo; -manfred -- Maybe some knowledge of some types of disagreeing and their relation can turn out to be useful: http://blog.createdebate.com/2008/04/07/writing-strong-arguments/It'll never be implemented, but it's a good idea. Along the same lines, (another good idea that'll never be implemented), is to assign a priority to a virtual function. A higher priority means that the virtual function will be called more. This allows the compiler to optimize out the function pointer invokation for high-priority virtual functions. -Craig
Jul 18 2008
Craig Black wrote:It'll never be implemented, but it's a good idea. Along the same lines, (another good idea that'll never be implemented), is to assign a priority to a virtual function. A higher priority means that the virtual function will be called more. This allows the compiler to optimize out the function pointer invokation for high-priority virtual functions.That optimization is not possible, because the compiler doesn't know if the virtual function is overridden or not. Bypassing the virtual dispatch will break the program. However, you can tell the compiler a virtual function will not be overridden by declaring it 'final', and the compiler will use direct rather than virtual dispatch (and it does this already).
Jul 18 2008
The following mixin code can be used to generate optimized code for specific, final types automatically. This can really speed up some inner loops if used carefully. It allows the compiler to inline at the cost of one dynamic cast. import std.stdio; string repl(string text, string what, string by) { string res; int i; while (i + what.length !> text.length) { if (text[i .. i+what.length] == what) { res ~= by; i += what.length; } else { res ~= text[i]; i ++; } } res ~= text[i .. $]; return res; } static assert(repl("foobarfobes", "ob", "kn") == "foknarfknes"); template ExpectCall(string VAR, string OP, TYPES...) { static if (!TYPES.length) const string ExpectCall = repl(OP, "$$", VAR)~"; "; else const string ExpectCall = "if (auto ec_var = cast("~TYPES[0]~") "~VAR~") { "~repl(OP, "$$", "ec_var")~"; } else { "~ExpectCall!(VAR, OP, TYPES[1 .. $])~" }"; } class A { void test() { writefln("test A"); } } final class B : A { void test() { writefln("test B"); } } final class C : A { void test() { writefln("test C"); } } void main() { A[] foo = [new A, new B, new C]; pragma(msg, ExpectCall!("entry", "$$.test()", "B", "C")); foreach (entry; foo) { mixin(ExpectCall!("entry", "$$.test()", "B", "C")); } }
Jul 18 2008
Manfred_Nowak wrote:Example: If two actions `a1',`a2' are based on a binary decision `b' then on a pure logical level one can code: if( b) a1.do; // actions have `do'- and `undo'-methods else a2.do; But if one knows, that the probability of `b' to be `true' is much greater than .5, then in order to use the precomputing capabilities of the CPU one would probably like to code: a1.do; if( !b){ a1.undo; a2.do; } The other case requires similar code. In this latter code the abstraction of a simple binary decision seems to be less obvious, which seems to be bad for maintenance. Of course one can annotate with comments. But since comments can be hints for defencies in the language, the question rises whether one should formalize this: if( b)note( p(b)>.8) a1.do; undo a1.undo; else a2; undo a2.undo; -manfredMSVC++ 2005 has this profile that you can run on the code and then it will use that to optimize the code to use the most common paths. I'm not sure if it also optimizes IF statements. I know it optimizes functions layout to be more cache friendly. -Joel
Jul 18 2008
JAnderson wrote:Manfred_Nowak wrote:The Sun compiler does this too. It's the code rearranging that's the killer feature here IMO. I love that the compiler can ensure that the code for heavily used functions doesn't cross page boundaries, etc. SeanExample: If two actions `a1',`a2' are based on a binary decision `b' then on a pure logical level one can code: if( b) a1.do; // actions have `do'- and `undo'-methods else a2.do; But if one knows, that the probability of `b' to be `true' is much greater than .5, then in order to use the precomputing capabilities of the CPU one would probably like to code: a1.do; if( !b){ a1.undo; a2.do; } The other case requires similar code. In this latter code the abstraction of a simple binary decision seems to be less obvious, which seems to be bad for maintenance. Of course one can annotate with comments. But since comments can be hints for defencies in the language, the question rises whether one should formalize this: if( b)note( p(b)>.8) a1.do; undo a1.undo; else a2; undo a2.undo; -manfredMSVC++ 2005 has this profile that you can run on the code and then it will use that to optimize the code to use the most common paths. I'm not sure if it also optimizes IF statements. I know it optimizes functions layout to be more cache friendly.
Jul 18 2008
JAnderson wrote:MSVC++ 2005 has this profile that you can run on the code and then it will use that to optimize the code to use the most common paths. I'm not sure if it also optimizes IF statements. I know it optimizes functions layout to be more cache friendly.The dmd profiler does this too. It emits a file, trace.def, which optimally orders functions based on the runtime profile, which you can then use as input to optlink.
Jul 18 2008
Reply to Walter,JAnderson wrote:Oh? Cool! Link?MSVC++ 2005 has this profile that you can run on the code and then it will use that to optimize the code to use the most common paths. I'm not sure if it also optimizes IF statements. I know it optimizes functions layout to be more cache friendly.The dmd profiler does this too. It emits a file, trace.def, which optimally orders functions based on the runtime profile, which you can then use as input to optlink.
Jul 18 2008
BCS wrote:Reply to Walter,http://www.digitalmars.com/ctg/trace.htmlJAnderson wrote:Oh? Cool! Link?MSVC++ 2005 has this profile that you can run on the code and then it will use that to optimize the code to use the most common paths. I'm not sure if it also optimizes IF statements. I know it optimizes functions layout to be more cache friendly.The dmd profiler does this too. It emits a file, trace.def, which optimally orders functions based on the runtime profile, which you can then use as input to optlink.
Jul 18 2008
Walter Bright Wrote:The dmd profiler does this too. It emits a file, trace.def, which optimally orders functions based on the runtime profile, which you can then use as input to optlink.Oh, good, so in the future you may do the last little step, adding to dmd a compilation flag to perform such profile-driven optimization, like the -fprofile-generate/-fprofile-use pair of flags of GCC. Bye, bearophile
Jul 18 2008
Walter Bright wrote:JAnderson wrote:That's cool! It sums over multiple runs as well. I might leave it on most of the time. -JoelMSVC++ 2005 has this profile that you can run on the code and then it will use that to optimize the code to use the most common paths. I'm not sure if it also optimizes IF statements. I know it optimizes functions layout to be more cache friendly.The dmd profiler does this too. It emits a file, trace.def, which optimally orders functions based on the runtime profile, which you can then use as input to optlink.
Jul 18 2008