|Bill Allombert on Tue, 25 Aug 2009 14:44:57 +0200|
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
|Re: TRY/CATCH is unnecessarily slow on OS X|
On Sat, Aug 15, 2009 at 01:45:18AM +0200, Lorenz Minder wrote: > Hi, > > The PARI TRY/CATCH exception handling is currently very slow on > Mac OS X (and probably *BSD, although I haven't checked that). I don't > know if Linux is affected but quite possibly not. Hello Lorenz, Thanks for reporting this issue. > How slow is it? Agonizingly slow. The attached "except.cc" computes > "gsqrt(2)" repeatedly, once with each call wrapped into a CATCH/TRY > block and once without the wrapping. With error checking, it's slower > by an order of magnitude: > > pari_perform$ time ./except n # No error checking. > > real 0m0.700s > user 0m0.694s > sys 0m0.005s > pari_perform$ time ./except p # W/ PARI exception handling. > > real 0m8.466s > user 0m5.799s > sys 0m2.660s On my amd64-linux laptop I get: %time ./expect n ./expect n 0,71s user 0,00s system 99% cpu 0,712 total %time ./expect p ./expect p 1,23s user 0,00s system 100% cpu 1,226 total This is still slow but more bearable. > Some would probably argue that not every tiny call must be wrapped into > a CATCH/TRY-block, but the fact is that doing this is sometimes > necessary, e.g., for wrapper libraries, or if you cannot or don't want > to reuse the PARI error handling mechanisms in your C program. Note that when using TRY/CATCH, you are effectively using the PARI error handling mechanism. > Why is it so slow? The problem is that the Mac OS X version of > setjmp/longjmp saves and restores the signal mask, which appears to take > an insane amount of time. Assuming that this is not necessary (if it > is, I think you have a bug on SysV), it is better to use a variant of > setjmp/longjmp that does not do this. Use _setjmp/_longjmp or possibly > sigsetjmp(,0)/siglongjmp() instead. I have to agree that all systems should behave the same. However my understanding of POSIX.1 is that setjmp/longjmp must not save and restore the signal mask, and non POSIX systems are not required to carry sigsetjmp/siglongjmp. > The attached patch does this as a proof of concept, and with it applied, > I get much better behaviour: > > pari_perform$ time ./except n > > real 0m0.700s > user 0m0.695s > sys 0m0.004s > pari_perform$ time ./except p > > real 0m0.810s > user 0m0.804s > sys 0m0.005s > > This patch breaks systems that do not have _setjmp(), so you probably > have to test for its existence in Configure. On my laptop, TRY/CATCH incurr a 80% penalty on the running time. We should do more timings. Cheers, Bill.