From: Stephan F. <def...@go...> - 2014-05-28 20:52:49
|
Hello, some users may have noticed, that sb-gmp can be quite fragile at times. This is in most part the result of internal (re)allocation from within GMP if the Lisp-side pre-allocated buffers are not big enough. Sometimes there is no way to prea-llocate in advance which was solved by copying from C to SBCL space with a factor 3 penalty. A have toyed with using the custom allocation method of GMP to pull all allocation to the Lisp side (apart from temporary/dynamic-extent with-alien C structure setup before calling into C). This new allocation scheme lives in the 'newalloc' branch of the sb-gmp development repository [1]. The new method works now well for me (on amd64) and I would appreciate feedback from others, especially from people who have problems with the current version in SBCL, whether this new approach yields better, stable results when exercising the test suite (use the one from the repository branch). Note, that this version does not yet work in conjunction with sb-mpfr (or only by accident). An overview of the pros and cons of the old and new method: old - pros: - mostly working - page pinnig when calling into C old - cons: - two methods of memory handling * memory fault when pre-allocation assumption is violated * factor 3 copying penalty when handling allocation within GMP * several different implementations for each case with different corner cases - finalizers required for GMP random states new - pros: - unified and overall simpler memory handling, more data structures/logic moved to the Lisp side instead of alien structures - appears to be more robust once I got the pointer-fiddling right - all allocation requests are handled within SBCL - robust against allocations and re-allocations from within GMP (no more memory faults due to allocation) - avoids copying from C memory space in all cases (no more factor 3 copying penalty) - no finalizers required new - cons: - requires without-gcing instead of page-pinning only - allocation calls from C into Lisp - GMP random state handling got a bit more complicated (but is well excercised within the test suite and appears to be robust). Regs, Stephan [1] https://github.com/sfrank/sb-gmp/tree/newalloc |
From: Alastair B. <ala...@gm...> - 2014-05-28 22:12:52
|
First thoughts: "Ugh." Second thoughts: - On cheneygc? WITH-PINNED-OBJECTS is already WITHOUT-GCING. No loss there. - On gencgc? Non-x86oid targets have an explicit pin list that should be easy to enable for x86oids as well, and there's no requirement to stack-allocate the conses. You can special-bind the free list to its value and then push onto it from C if necessary. - On both, the runtime code can be made to do a certain amount of allocation straight-up, without having to do the whole call-into-c thing. The lead-up to this level of cleverness is cleaning up and exposing more of the runtime interfaces for contribs and outside systems to use, which may not be entirely a good thing, or to move some of the logic required for sb-gmp over to the runtime (which has a certain amount of precedent already). And, of course, others may disagree entirely with this whole idea. -- Alastair Bridgewater On Wed, May 28, 2014 at 4:52 PM, Stephan Frank <def...@go...>wrote: > Hello, > > some users may have noticed, that sb-gmp can be quite fragile at times. > This is in most part the result of internal (re)allocation from within > GMP if the Lisp-side pre-allocated buffers are not big enough. Sometimes > there is no way to prea-llocate in advance which was solved by copying > from C to SBCL space with a factor 3 penalty. > > A have toyed with using the custom allocation method of GMP to pull all > allocation to the Lisp side (apart from temporary/dynamic-extent > with-alien C structure setup before calling into C). > > This new allocation scheme lives in the 'newalloc' branch of the sb-gmp > development repository [1]. > > The new method works now well for me (on amd64) and I would appreciate > feedback from others, especially from people who have problems with the > current version in SBCL, whether this new approach yields better, stable > results when exercising the test suite (use the one from the repository > branch). > > Note, that this version does not yet work in conjunction with sb-mpfr > (or only by accident). > > > An overview of the pros and cons of the old and new method: > > old - pros: > - mostly working > - page pinnig when calling into C > > old - cons: > - two methods of memory handling > * memory fault when pre-allocation assumption is violated > * factor 3 copying penalty when handling allocation within GMP > * several different implementations for each case with different > corner cases > - finalizers required for GMP random states > > > new - pros: > - unified and overall simpler memory handling, more data > structures/logic moved to the Lisp side instead of alien structures > - appears to be more robust once I got the pointer-fiddling right > - all allocation requests are handled within SBCL > - robust against allocations and re-allocations from within GMP (no more > memory faults due to allocation) > - avoids copying from C memory space in all cases (no more factor 3 > copying penalty) > - no finalizers required > > new - cons: > - requires without-gcing instead of page-pinning only > - allocation calls from C into Lisp > - GMP random state handling got a bit more complicated (but is well > excercised within the test suite and appears to be robust). > > > Regs, > Stephan > > > [1] https://github.com/sfrank/sb-gmp/tree/newalloc > > > ------------------------------------------------------------------------------ > Time is money. Stop wasting it! Get your web API in 5 minutes. > www.restlet.com/download > http://p.sf.net/sfu/restlet > _______________________________________________ > Sbcl-devel mailing list > Sbc...@li... > https://lists.sourceforge.net/lists/listinfo/sbcl-devel > |
From: Stephan F. <def...@go...> - 2014-05-28 23:09:47
|
On 29.05.2014 00:12, Alastair Bridgewater wrote: > First thoughts: "Ugh." well, OK; to me that approach overall looked a lot cleaner than the current variant (though I admit that whole call into lisp for allocation isn't so great) > - On both, the runtime code can be made to do a certain amount of > allocation straight-up, without having to do the whole call-into-c thing. Do you mean call-into-lisp? How would this prevent the malloc calls from within GMP? > > The lead-up to this level of cleverness is cleaning up and exposing more > of the runtime interfaces for contribs and outside systems to use, which > may not be entirely a good thing, or to move some of the logic required > for sb-gmp over to the runtime (which has a certain amount of precedent > already). I am afraid you lost me somewhere in there. Also, isn't it somewhat "ugh" as well to have an optional contrib trigger such changes to the runtime? > > And, of course, others may disagree entirely with this whole idea. > > -- Alastair Bridgewater > > > On Wed, May 28, 2014 at 4:52 PM, Stephan Frank <def...@go... > <mailto:def...@go...>> wrote: > > Hello, > > some users may have noticed, that sb-gmp can be quite fragile at times. > This is in most part the result of internal (re)allocation from within > GMP if the Lisp-side pre-allocated buffers are not big enough. Sometimes > there is no way to prea-llocate in advance which was solved by copying > from C to SBCL space with a factor 3 penalty. > > A have toyed with using the custom allocation method of GMP to pull all > allocation to the Lisp side (apart from temporary/dynamic-extent > with-alien C structure setup before calling into C). > > This new allocation scheme lives in the 'newalloc' branch of the sb-gmp > development repository [1]. > > The new method works now well for me (on amd64) and I would appreciate > feedback from others, especially from people who have problems with the > current version in SBCL, whether this new approach yields better, stable > results when exercising the test suite (use the one from the repository > branch). > > Note, that this version does not yet work in conjunction with sb-mpfr > (or only by accident). > > > An overview of the pros and cons of the old and new method: > > old - pros: > - mostly working > - page pinnig when calling into C > > old - cons: > - two methods of memory handling > * memory fault when pre-allocation assumption is violated > * factor 3 copying penalty when handling allocation within GMP > * several different implementations for each case with different > corner cases > - finalizers required for GMP random states > > > new - pros: > - unified and overall simpler memory handling, more data > structures/logic moved to the Lisp side instead of alien structures > - appears to be more robust once I got the pointer-fiddling right > - all allocation requests are handled within SBCL > - robust against allocations and re-allocations from within GMP (no more > memory faults due to allocation) > - avoids copying from C memory space in all cases (no more factor 3 > copying penalty) > - no finalizers required > > new - cons: > - requires without-gcing instead of page-pinning only > - allocation calls from C into Lisp > - GMP random state handling got a bit more complicated (but is well > excercised within the test suite and appears to be robust). > > > Regs, > Stephan > > > [1] https://github.com/sfrank/sb-gmp/tree/newalloc > > ------------------------------------------------------------------------------ > Time is money. Stop wasting it! Get your web API in 5 minutes. > www.restlet.com/download <http://www.restlet.com/download> > http://p.sf.net/sfu/restlet > _______________________________________________ > Sbcl-devel mailing list > Sbc...@li... > <mailto:Sbc...@li...> > https://lists.sourceforge.net/lists/listinfo/sbcl-devel > > |
From: Alastair B. <ala...@gm...> - 2014-05-28 23:45:15
|
On Wed, May 28, 2014 at 7:09 PM, Stephan Frank <def...@go...>wrote: > On 29.05.2014 00:12, Alastair Bridgewater wrote: > >> First thoughts: "Ugh." >> > > well, OK; to me that approach overall looked a lot cleaner than the > current variant (though I admit that whole call into lisp for allocation > isn't so great) Exactly, call into lisp for allocation? Ugh. > > - On both, the runtime code can be made to do a certain amount of >> allocation straight-up, without having to do the whole call-into-c thing. >> > > Do you mean call-into-lisp? How would this prevent the malloc calls from > within GMP? > Sorry, yes. You'd need a bit in C that knows how to safely allocate whatever object you need and arrange for it to be pinned, but it saves the whole call-into-lisp and return dance. > > >> The lead-up to this level of cleverness is cleaning up and exposing more >> of the runtime interfaces for contribs and outside systems to use, which >> may not be entirely a good thing, or to move some of the logic required >> for sb-gmp over to the runtime (which has a certain amount of precedent >> already). >> > > I am afraid you lost me somewhere in there. Also, isn't it somewhat "ugh" > as well to have an optional contrib trigger such changes to the runtime? > It is, but as I said, there's precedent. And what I'm sortof suggesting here is building an interface so that alien code doing lisp heap allocation is semi-supported. > >> And, of course, others may disagree entirely with this whole idea. >> >> -- Alastair Bridgewater >> >> >> On Wed, May 28, 2014 at 4:52 PM, Stephan Frank <def...@go... >> <mailto:def...@go...>> wrote: >> >> Hello, >> >> some users may have noticed, that sb-gmp can be quite fragile at >> times. >> This is in most part the result of internal (re)allocation from within >> GMP if the Lisp-side pre-allocated buffers are not big enough. >> Sometimes >> there is no way to prea-llocate in advance which was solved by copying >> from C to SBCL space with a factor 3 penalty. >> >> A have toyed with using the custom allocation method of GMP to pull >> all >> allocation to the Lisp side (apart from temporary/dynamic-extent >> with-alien C structure setup before calling into C). >> >> This new allocation scheme lives in the 'newalloc' branch of the >> sb-gmp >> development repository [1]. >> >> The new method works now well for me (on amd64) and I would appreciate >> feedback from others, especially from people who have problems with >> the >> current version in SBCL, whether this new approach yields better, >> stable >> results when exercising the test suite (use the one from the >> repository >> branch). >> >> Note, that this version does not yet work in conjunction with sb-mpfr >> (or only by accident). >> >> >> An overview of the pros and cons of the old and new method: >> >> old - pros: >> - mostly working >> - page pinnig when calling into C >> >> old - cons: >> - two methods of memory handling >> * memory fault when pre-allocation assumption is violated >> * factor 3 copying penalty when handling allocation within GMP >> * several different implementations for each case with different >> corner cases >> - finalizers required for GMP random states >> >> >> new - pros: >> - unified and overall simpler memory handling, more data >> structures/logic moved to the Lisp side instead of alien structures >> - appears to be more robust once I got the pointer-fiddling right >> - all allocation requests are handled within SBCL >> - robust against allocations and re-allocations from within GMP (no >> more >> memory faults due to allocation) >> - avoids copying from C memory space in all cases (no more factor 3 >> copying penalty) >> - no finalizers required >> >> new - cons: >> - requires without-gcing instead of page-pinning only >> - allocation calls from C into Lisp >> - GMP random state handling got a bit more complicated (but is well >> excercised within the test suite and appears to be robust). >> >> >> Regs, >> Stephan >> >> >> [1] https://github.com/sfrank/sb-gmp/tree/newalloc >> >> ------------------------------------------------------------ >> ------------------ >> Time is money. Stop wasting it! Get your web API in 5 minutes. >> www.restlet.com/download <http://www.restlet.com/download> >> >> http://p.sf.net/sfu/restlet >> _______________________________________________ >> Sbcl-devel mailing list >> Sbc...@li... >> <mailto:Sbc...@li...> >> https://lists.sourceforge.net/lists/listinfo/sbcl-devel >> >> >> > |
From: Stephan F. <def...@go...> - 2014-07-14 21:29:28
|
On 29.05.2014 01:45, Alastair Bridgewater wrote: > Do you mean call-into-lisp? How would this prevent the malloc calls > from within GMP? > > > Sorry, yes. You'd need a bit in C that knows how to safely allocate > whatever object you need and arrange for it to be pinned, but it saves > the whole call-into-lisp and return dance. Howdy, I now have some time to approach the above proposal to add the sb-gmp specific allocation to the C part of the runtime, since allocation via Lisp callbacks was understandably not welcomed with open arms. However, after some initial digging, things are not as clear to me as I had hoped, which most likely stems from misunderstanding or missing information about the runtime. Since reading about the SBCL internals did not lead to further insights in this regard, I'd kindly ask for some hand-holding with the following questions or any additional comments concerning the approach: - So far I thought a bignum consists of a header describing the bignum tag bits and the number of limbs followed by a vector of limbs (i.e. simply a vector of word). Since SB-GMP works, this assumption cannot be completely wrong. However, the structure definition in genesis/bignum.h is as follows: struct bignum { lispobj header; sword_t digits[1]; }; Where in there is the limb vector of varying size, since digits is only of length 1? - A had hoped to use alloc_number in alloc.c of the runtime, though again this only appears to allocate bignums with at most one limb. Is this observation correct? - There is a Lisp function %allocate-bignum (bignum.lisp) which again simply calls %allocate-bignum which I expected to be a low-level assembly or C function of the same name. However, I could not find its definition anywhere, so where is it? - How are such C functions made known to the Lisp runtime such that they can be passed to C functions via FFI calls? - When allocating with pa_alloc, how can the allocated region be pinned right then, and how can I remove that pinning later from within SBCL? I hope answers to the above questions will help get on the right track, so thank a lot in advance. Kind regards, Stephan |
From: Alastair B. <ala...@gm...> - 2014-07-15 05:01:57
|
On Mon, Jul 14, 2014 at 5:29 PM, Stephan Frank <def...@go...> wrote: > On 29.05.2014 01:45, Alastair Bridgewater wrote: > > Do you mean call-into-lisp? How would this prevent the malloc calls > > from within GMP? > > > > > > Sorry, yes. You'd need a bit in C that knows how to safely allocate > > whatever object you need and arrange for it to be pinned, but it saves > > the whole call-into-lisp and return dance. > > Howdy, > > I now have some time to approach the above proposal to add the sb-gmp > specific allocation to the C part of the runtime, since allocation via > Lisp callbacks was understandably not welcomed with open arms. > > However, after some initial digging, things are not as clear to me as I > had hoped, which most likely stems from misunderstanding or missing > information about the runtime. Since reading about the SBCL internals > did not lead to further insights in this regard, I'd kindly ask for some > hand-holding with the following questions or any additional comments > concerning the approach: > > - So far I thought a bignum consists of a header describing the bignum > tag bits and the number of limbs followed by a vector of limbs (i.e. > simply a vector of word). Since SB-GMP works, this assumption cannot be > completely wrong. However, the structure definition in genesis/bignum.h > is as follows: > > struct bignum { > lispobj header; > sword_t digits[1]; > }; > > Where in there is the limb vector of varying size, since digits is only > of length 1? > There's no bounds-check on access to digits, it's always an odd number of words and at least one word. If you look at the definition in SYS:SRC;COMPILER;GENERIC;OBJDEF.LISP, you'll find the slot marked as :REST-P T, meaning "there is an unbounded amount of data starting at this point". - A had hoped to use alloc_number in alloc.c of the runtime, though > again this only appears to allocate bignums with at most one limb. Is > this observation correct? > Sounds about right if alloc_number only needs to allocate signed integers corresponding to a machine word in width. - There is a Lisp function %allocate-bignum (bignum.lisp) which again > simply calls %allocate-bignum which I expected to be a low-level > assembly or C function of the same name. However, I could not find its > definition anywhere, so where is it? > It's a bit magic, but the :ALLOC-TRANS option to DEFINE-PRIMITIVE-OBJECT BIGNUM in SYS:SRC;COMPILER;GENERIC;OBJDEF.LISP is the definition. This winds up going through either the VAR-ALLOC or FIXED-ALLOC VOPs (in SYS:SRC;COMPILER;TARGET;ALLOC.LISP). - How are such C functions made known to the Lisp runtime such that they > can be passed to C functions via FFI calls? > As mentioned above, %ALLOCATE-BIGNUM is an open-coded primitive operation in the compiler, for which you found the "interpreter stub" (an out-of-line expansion that causes it to be FBOUND and allows passing the operation around as a function reference). - When allocating with pa_alloc, how can the allocated region be pinned > right then, and how can I remove that pinning later from within SBCL? > Umm... Good luck? I'm starting to suspect that the currently-defined interface for pa_alloc is broken and wrong, primarily with respect to precisely this and asynchronous interrupts. My original plan for this was to make all gencgc backends honor an explicit pin list (as opposed to now, when just the non-x86oid backends use an explicit pin list), then temporarily wedge a new CONS onto the list for the pointer being allocated. I hope answers to the above questions will help get on the right track, > so thank a lot in advance. > > > Kind regards, > Stephan > -- Alastair Bridgewater |
From: Stephan F. <def...@go...> - 2014-07-15 09:15:50
|
> Sounds about right if alloc_number only needs to allocate signed integers > corresponding to a machine word in width. > > - There is a Lisp function %allocate-bignum (bignum.lisp) which again >> simply calls %allocate-bignum which I expected to be a low-level >> assembly or C function of the same name. However, I could not find its >> definition anywhere, so where is it? >> > > It's a bit magic, but the :ALLOC-TRANS option to DEFINE-PRIMITIVE-OBJECT > BIGNUM in SYS:SRC;COMPILER;GENERIC;OBJDEF.LISP is the definition. This > winds up going through either the VAR-ALLOC or FIXED-ALLOC VOPs (in > SYS:SRC;COMPILER;TARGET;ALLOC.LISP). > > - How are such C functions made known to the Lisp runtime such that they >> can be passed to C functions via FFI calls? >> > > As mentioned above, %ALLOCATE-BIGNUM is an open-coded primitive operation > in the compiler, for which you found the "interpreter stub" (an out-of-line > expansion that causes it to be FBOUND and allows passing the operation > around as a function reference). > OK, now say, I want to use the above alloc_number from runtime/alloc.c to pass it as an argument to a GMP/C function via Lisp. Is there a mechanism that makes function from the C runtime code known by name to the Lisp process such that they can be referenced in Lisp, even though they adhere to the C calling convention? Stephan |
From: Stephan F. <def...@go...> - 2014-07-16 20:29:58
|
Hi, I've added three functions to runtime;alloc.c/h because I make use of alloc_unboxed already in there. The current version is in the 'newalloc' branch of sb-gmp [1] including the adapted run-time. All tests pass for me; comments appreciated. Regs, Stephan [1] https://github.com/sfrank/sb-gmp/tree/newalloc |
From: Nikodemus S. <nik...@ra...> - 2014-05-29 10:17:40
|
On 29 May 2014 02:45, Alastair Bridgewater <ala...@gm...> wrote: > And what I'm sortof suggesting here is building an interface so that alien > code doing lisp heap allocation is semi-supported. I can foresee other use-cases for this as well. It's much nicer to have the GC aware of "foreign" memory pressure as well, since it's easy to end up with tiny (dead) lisp objects holding huge foreign objects... and never getting that memory back because the lisp side allocation is small enough not to trigger a GC which would run the finalizers. Cheers, -- nikodemus |
From: <me...@re...> - 2014-05-29 10:59:14
|
Nikodemus Siivola <nik...@ra...> writes: > On 29 May 2014 02:45, Alastair Bridgewater > <ala...@gm...> wrote: > >> And what I'm sortof suggesting here is building an interface so that alien >> code doing lisp heap allocation is semi-supported. > > I can foresee other use-cases for this as well. > > It's much nicer to have the GC aware of "foreign" memory pressure as > well, since it's easy to end up with tiny (dead) lisp objects holding > huge foreign objects... and never getting that memory back because the > lisp side allocation is small enough not to trigger a GC which would > run the finalizers. One thing that you may or may not be considering is that foreign memory pressure comes in several sizes: malloc(), and cuMemAlloc (with a separate heap for each gpu). Going further, other, non-memory external resources such as fds can be tied to lisp objects as well. |
From: Nikodemus S. <nik...@ra...> - 2014-05-29 18:03:55
|
On 29 May 2014 13:59, Gábor Melis <me...@re...> wrote: > One thing that you may or may not be considering is that foreign memory > pressure comes in several sizes: malloc(), and cuMemAlloc (with a > separate heap for each gpu). Going further, other, non-memory external > resources such as fds can be tied to lisp objects as well. Oh, absolutely -- but malloc() pressure alone can be quite bad enough. If it can be solved so users don't have to do tricks like explicit deallocation via UWP the world is a better place even if there are still troublesome other resources which can cause similar issues. (I have some thoughts on the more general problem, but they veer quite far from SBCL *and* are pretty half formed, so they're probably better saved for a time and place where there is beer...) Cheers, -- nikodemus |