<div dir="ltr"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">I did some experiments about a year ago with different hand-written <br>
assembly implementations of error handling control flow patterns and it <br>
was really hard to beat the checked return on recent Intel hardware. <br>
This was a microbenchmark, so didn't see effects from increased cache usage. </blockquote><div>That's a very interesting result. Thanks for the insights!</div><div>Just out of curiosity, did you remember how much slowdown you get between checked return and no check at all (simply ignore the error)?</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>There's also the fact that explicit error checking lets the programmer <br>
simplify the CFG explicitly.  If you're calling two functions that don't <br>
depend on any data flow between them, you can do something like:<br>
<br>
auto a = someFn();<br>
auto b = someOtherFn();<br>
if (!a || !b)<br>
        doSomeErrorHandlingStuffs();<br>
<br>
Transforming exception-driven code into this structure would be an <br>
invalid transform unless the compiler could prove that someOtherFn() has <br>
no observable side effects.</div></blockquote><div>I didn't fully understand this part. If someOtherFn() has obversable side effects, you cannot convert <br></div><div>auto a = someFn(); if (!a) { ... }<br></div><div>auto b = someOtherFn() if (!b) { ... }</div><div>to your code snippet either..<br></div><div><font color="#888888"><br></font></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">David Chisnall via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>> 于2020年8月14日周五 上午7:55写道:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 14/08/2020 03:39, David Blaikie via llvm-dev wrote:<br>
> Once you get past the nothrow default problems, then you probably have<br>
> to deal with the performance tradeoffs between the current strategy<br>
> for exception implementations (table based, etc) compared to the<br>
> tradeoffs for explicit error handling. You'd probably find that using<br>
> exceptions for/every/  error return would not be the right perf<br>
> tradeoff for many use cases where errors are at least somewhat common.<br>
> So you'd probably end up with a hybrid solution - some things using<br>
> exceptions where the failure is rare/going to be costly anyway<br>
> (stopping the process, showing an error to a user/asking for user<br>
> input about retrying, etc) and then still using explicit error<br>
> handling for other things.<br>
<br>
There's a second-order effect here too.  Everyone knows exceptions are <br>
slow, so everyone writes fast-path code with explicit error returns.  As <br>
a result, modern branch predictors are *really* good at predicting the <br>
no-error case.  A lot of the arguments about checked return values being <br>
slow date back to in-order processors where adding any instructions on <br>
the fast path was always a slowdown, even if they were not-taken branches.<br>
<br>
I did some experiments about a year ago with different hand-written <br>
assembly implementations of error handling control flow patterns and it <br>
was really hard to beat the checked return on recent Intel hardware. <br>
This was a microbenchmark, so didn't see effects from increased cache usage.<br>
<br>
There's also the fact that explicit error checking lets the programmer <br>
simplify the CFG explicitly.  If you're calling two functions that don't <br>
depend on any data flow between them, you can do something like:<br>
<br>
auto a = someFn();<br>
auto b = someOtherFn();<br>
if (!a || !b)<br>
        doSomeErrorHandlingStuffs();<br>
<br>
Transforming exception-driven code into this structure would be an <br>
invalid transform unless the compiler could prove that someOtherFn() has <br>
no observable side effects.<br>
<br>
David<br>
<br>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div>