|Bill Allombert on Sat, 05 Sep 2009 13:49:03 +0200|
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
|Re: TRY/CATCH is unnecessarily slow on OS X|
On Thu, Sep 03, 2009 at 08:43:44AM +0200, Lorenz Minder wrote: > Hi, > > I find this surprising indeed. I did a couple of runs with 64bit > compiles on OS X and NetBSD, and I can't observe anything that bad when > _setjmp / _longjmp is used. (I get a ~20% slowdown or so relative to no > error checking. It's a bit more with Linux on G4, but still only ~30%.) > > The numbers are later in the mail. Thanks, I will retry next week on more proper hardware. > I went and checked the POSIX spec this afternoon. These are the main Was it the standard or the draft ? It would not be te only place they differ. > points: > > 1) It is unspecified whether setjmp() saves the signal mask. (They > don't say anything about that in the setjmp manpage itself, but > elsewhere they explicitly say it's unspecified.) > > 2) _setjmp() must not store the signal mask. > > 3) sigsetjmp(,0) does not have to store the signal mask, but it can. > sigsetjmp(,1) must store it. > > 4) They say new software should not use _setjmp, but rather sigsetjmp. > > I think that given that sigsetjmp(,0) may store the signal mask, the > advice 4) seems dodgy. What is worse, this is misleading: if you let out performance (which is not a POSIX concern), then the issue is that siglongjmp can restore the signal mask even if one do not want to. > > On my laptop, TRY/CATCH incurr a 80% penalty on the running time. We > > should do more timings. > > Yes, indeed. See also the bottom of this mail. > > BA: > > On Mon, Aug 24, 2009 at 01:03:13AM -0700, Lorenz Minder wrote: > > err_catch is only supposed to be used through the TRY/CATCH macros so this is > > not an issue. What is more problematic is changing the type of DATA->env: > > User code might do setjmp(GP_DATA->env) and be broken by the change. > > Ok, thanks for clarifying. Actually I have a plan to remove GP_DATA->env entirely and add a call-back (cb_pari_err_restore) that would handle recovery from error. Please see bug #958 for detail. This is still very preliminary. > > So maybe we could use _setjmp/_getjmp instead of sigsetjmp/siglongjmp. > > We can't use _longjmp() on a jmp_buf that has been created with setjmp() > or vice versa, so I don't think this will work. Looking at the code > again, it seems that the setjmp(GP_DATA->env)/longjmp(GP_DATA->env) > business is separate from the TRY/CATCH/err_catch() infrastructure, so > one option would be only to change TRY/CATCH/err_catch() to use > _setjmp/_longjmp and leave the GP_DATA->env stuff as is. It would be > wise, though, to make sure that "pari_setjmp(GP_DATA->env)" would cause > a compile-time error, so as to avoid erroneous use of pari_setjmp(). I > think that can be arranged. > > This assumes that setjmp(GP_DATA->env) is only called infrequently, and > is hence not performance-critical. I believe this holds at least for how > it's used in GP. > > What do you think? err_catch only purpose is to implement the current stacked exceptions system which I find wholly inedequate and hope to replace. Furthermore, TRY/CATCH is not documented currently, and mostly here to implement the gp trap() function, which has its load of problem. Adding a call-back 'cb_pari_err_restore' seems a better solution. > I was actually going to propose a small change that makes it possible > for users to avoid anything setjmp()/longjmp() based, provided they can > come up with a viable alternative. The idea is as follows. I think it would be better to provide the user with the mean to implement their own TRY/CATCH alternative, and keep the setjmp()/longjmp() one for internal libpari use. But the hard part with exceptions is to recover from them safely and without leaking resource. Cheers, Bill.