On Fri, Mar 1, 2019 at 8:13 AM Jason E. Aten <[email protected]> wrote: > > If I include a chunk of assembly .s code in my Go code, does my program pay > the CGO transition cost of locking and changing to a C stack?
No. The assembly function is simply called just as a Go function is called. > I'm pretty sure the answer is no. But my knowledge of the Go internals is low > enough that I thought I would like confirm that before I go pulling in .s > code. > > Then for numerical work, if I need to call some Fortran 90 compiled library > routines, does it not just look like assembly? I suppose not... in the sense > that it makes certain assumptions about being able to grow the stack it is > running on without running out of space. Are there assumptions beyond the > stack that are used? Probably some "standard library" runtime dependencies? Go assembly code is compiled by the Go assembler, cmd/asm. The author of the assembly code is required to specify how much stack space the assembly function requires, in the TEXT pseudo-op that introduces the function. For more about this, see https://golang.org/doc/asm. The cmd/asm program will use that user declaration to insert a function prologue that ensures that enough stack space is available, copying the stack if necessary. The cmd/asm program will also produce a stack map that the garbage collector will use when tracing back the stack; in practice it's quite difficult for the assembler code to define this stack map as anything other than "this stack contains no pointers", but see runtime/funcdata.h. In any case, your Fortran 90 code will have none of that information. Of course, if you know the exact stack usage of your Fortran code, and if the code never stores pointers on the stack, then you could with some effort write Go assembly code that defines the appropriate stack information and then calls the Fortran code. I think that would, but it would require a lot of manual hand-holding. > So on to my central question: Can the CGO transition stack switching cost be > minimized by telling Go to run my main (single threaded) Go routine on a C > thread to start with? In other words, can I minimize the CGO switching cost > by doing runtime.LockOSThread() or similar? > > > It seems like if we are already on a C thread, then perhaps *some large > > part* of the cost of Go -> f90 can be avoided. Of course the Go compiler > > doesn't know we are on a C thread in the general case, right(?), so it > > probably can't optimize those transitions by omitting change-the-stack code. This doesn't work, because the runtime expects to be able to use the C thread stack in some cases to handle scheduling between goroutines. You can't run general Go code on that stack. Note that LockOSThread does not cause code to run on the C thread stack. It causes the goroutine to only be scheduled on that thread. Also, while there is a cost to the fact that cgo changes stack, there are larger costs to 1) telling the Go scheduler that the code is leaving Go and entering C; 2) changing from the Go calling convention to the C calling convention. Eliminating the stack switching costs, while not entirely negligible, would not make cgo calls as fast as Go calls. > Returning to the original throught about .s code, what would happen if that > code tried to grow the stack too far? Just crash? Is there guidance about > how far assembly can grow the stack before it needs to check back with the > runtime? The assembly can grow the stack exactly as far as the TEXT declaration said that the stack would grow. Any farther may lead to memory corruption. Ian -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
