|
hackbunny posted:c++ exceptions have zero overhead... in terms of code that's executed. in terms of code size and extra metadata, though, they can be on the heavy side. you need extra code for unwinding when your stack frame is skipped, but in many (not all cases) you can recycle it for regular scope exit unwinding. but the real overhead is in all the metadata: for each instruction of a function that may be involved in unwinding, what objects need to be unwound at that point of the functions and how (not literally for each instruction, the metadata stores ranges of instructions instead); for each function, how to pop its frame off the stack (often in the form of bitcode that tells you what registers you should pop a stack slot into and so on, basically how to run the function prolog in reverse); enough runtime type information to make a copy of the exception object and match it to the catch statements; etc. if no exceptions are thrown (the expectation), then all of this is completely invisible what's .net any cpu exception handling like in comparison to x86?
|
# ? Sep 24, 2017 18:36 |
|
|
# ? May 26, 2024 04:08 |
|
love your effortposts
|
# ? Sep 24, 2017 20:02 |
|
cinci zoo sniper posted:1) https://www.w3schools.com/sql/default.asp i actually unironically forgot that w3 did non-web stuff ToadStyle posted:Code Wars has SQL poo poo if you want to push him to do more than just `SELECT * FROM whatevers WHERE`. i think a few of our "experienced" devs could do with this tbh
|
# ? Sep 24, 2017 20:12 |
|
update to my last post: we did it, here's the Jaguar GPU performing all the calculations necessary to draw a line in any direction and telling the blitter to do it
|
# ? Sep 24, 2017 20:41 |
|
my only memory of the jaguar is seeing boxes and boxes of consoles at a KB toys priced at like $20. with nobody buying.
|
# ? Sep 24, 2017 20:54 |
|
uncurable mlady posted:what's .net any cpu exception handling like in comparison to x86? I have no idea about .net exception handling actually, but it's probably safe to say that, being microsoft, they reused what they already had (at least in terms of know-how), i.e. windows exception handling, despite once again there not being any good reason to do so. there are explicit provisions in windows exception handling for dynamically generated code (unlike mono, .net has never had an interpreter, all code is compiled to native first) there is one advantage to having a single shared exception handling ABI for all languages, to be fair: uniform unwinding. you can have c++ function butt() that calls .net function fart() that in turns calls c++ function smell(); smell() can throw an exception that's caught in butt(), and all the finally blocks in fart() will be triggered, even if no possible .net catch statement could match the c++ exception. of course you don't need a framework as comprehensive as windows exceptions (which also supports handling things like page faults - the main rationale behind recoverable exceptions - effectively being a much programmer-friendlier version of posix signals) to do so hackbunny fucked around with this message at 20:58 on Sep 24, 2017 |
# ? Sep 24, 2017 20:55 |
|
akadajet posted:my only memory of the jaguar is seeing boxes and boxes of consoles at a KB toys priced at like $20. with nobody buying. i remember boxes of sega saturns at toys-r-us for $50 when i was there buying... some super nintendo game, i don't remember what i was too busy playing whatever was on the n64 kiosk
|
# ? Sep 24, 2017 20:58 |
|
hackbunny posted:all the finally blocks in fart() will be triggered, even if no possible .net catch statement could match the c++ exception
|
# ? Sep 24, 2017 21:02 |
|
akadajet posted:my only memory of the jaguar is seeing boxes and boxes of consoles at a KB toys priced at like $20. with nobody buying. same but for virtuaboys
|
# ? Sep 24, 2017 21:09 |
|
hackbunny posted:c++ exceptions have zero overhead... in terms of code that's executed. Ah, sorry. I misinterpreted what we were calling overhead here. I guess I was just thinking about the efficiency of actually thowing/longjmping.
|
# ? Sep 24, 2017 21:10 |
|
huh, neat. my only real take on exceptions in .net/Windows in general is that they're slow as poo poo, although the post about windows exceptions might help explain why that is.
|
# ? Sep 24, 2017 21:23 |
|
ToadStyle posted:Oh wow that's actually pretty rad. I don't know if it's actually legal in the c++/.net case (I'm pretty sure .net specifically stops exceptions at native/managed borders), but it's a common feature of exception handling ABIs. the Unwind abi used on linux and many other oses for example, was explicitly designed to support both c++ and java code on the same stack - the spec itself mentions it uncurable mlady posted:huh, neat. my only real take on exceptions in .net/Windows in general is that they're slow as poo poo, although the post about windows exceptions might help explain why that is. windows exceptions were primarily designed to replace unix signals to handle runtime errors like divisions by zero, page faults etc. whereas unix signals handle errors like those with a single globally set handler function (mirroring how the underlying cpu fault is handled by the kernel), windows puts itself as the handler, and then uses structured dispatching to handle faults like they were exceptions as I mentioned, this adds overhead to unwinding: in the search for an exception handler, you can't unwind the stack (i.e. destroy local variables and lower the stack function by function), because if a handler "fixes" the error and tells you to resume execution, you can't go back, unwinding has irreversibly destroyed the information that you needed to resume execution. so what you do is walk the stack with a virtual unwind (you only pretend to lower the stack, by running a miniature cpu emulator with its own emulated stack pointer, that executes function prologs in reverse), and you call handlers to look for a catch or resume; when you find a catch statement, you do another virtual unwind to call the cleanup handlers (e.g. finally blocks or c++ destructors of local variables), and then you copy the virtual context to the hardware context to resume execution at the catch statement ... but it also adds overhead to throwing! since the exception handling system is designed to handle cpu faults, it requires a trap frame for each throw, i.e. a copy of all cpu registers pushed on top of the stack. this has non-trivial overhead in comparison, the Unwind ABI is much, much simpler: a throw immediately starts unwinding, lowering the stack until the next frame with an exception handler; that exception handler either resumes execution at an appropriate catch site, or it unwinds to the next frame with a handler; and so on, recursively, until an appropriate catch (or the bottom of the stack) is reached. nothing is pushed on top of the faulting frame, which becomes immediately inaccessible: any information about the throw site must be captured in the exception object (think for example the stack backtrace in Java), or it's lost forever. for this reason, Unwind ABI exception objects are heap allocated and must have a destructor. in comparison and contrast, windows exceptions are stack allocated on the throw site and can't have a destructor - it's perfectly legal and expected to just point to all pertinent information on the live stack, since it remains accessible and untouched for the whole duration of unwinding. this is visible at a high level too: on c++ compilers that use windows exceptions as the underlying mechanism, exception objects are always copied at least once, as they are stack-allocated at the throw site, and then copied to the catch site (with a little imagination, though, you can very easily implement Unwind-like heap-allocated exceptions) another non-obvious source of overhead is that, if a debugger is currently attached to the process, exceptions are raised with a syscall instead of simply pushing the registers on the stack and calling the dispatcher (originally, exceptions were always thrown with the system call, regardless of whether a debugger was present or not, adding even more overhead) hackbunny fucked around with this message at 22:33 on Sep 24, 2017 |
# ? Sep 24, 2017 22:29 |
|
oh boy my first "real" rust hobby project i put out there is getting used and people are commenting on it. now i get a whole new class of people to disappoint with my programming
|
# ? Sep 24, 2017 23:58 |
|
I’m writing a pretty “basic” (log reservation and cleaning blocks in overprovisioned space) flash translation layer for an SSD and I have a new appreciation for these stupid devices Implementing garbage collection and wear leveling in a way that you don’t trash performance or your NAND erase cycles is tricky, and I haven’t put a restriction on my bookkeeping memory yet
|
# ? Sep 24, 2017 23:59 |
|
this is mostly spot-on but i want to clarify that libUnwind also supports resumable exceptions and so also does a two-phase search. in fact that's also required with non-resumable exceptions for compatibility reasons, because for whatever reason throwing an exception without a handler historically hasn't actually unwound the stack before calling std::terminate (the c++ standard allows this, it's unspecified). we had problems with that in llvm for awhile because we were trying to emit destructors in a way that made the frame essentially catch and rethrow, and that's not actually semantically correct also unlike the windows unwinder, libUnwind basically isn't allowed to have any persistent state during unwind. this is because it doesn't have any persistent stack storage — it only has stack frames during calls to _Unwind_RaiseException or _Unwind_Resume, which it has to exit in order to enter a function to run cleanups or handlers — and the only persistent heap storage it gets is the exception object, which can be thrown multiple times simultaneously because of std::exception_ptr. so e.g. it can't remember anything it learned during the search phase and use that when unwinding, or at least it has to degrade cleanly when the exception object becomes shared
|
# ? Sep 25, 2017 01:39 |
gonadic io posted:oh boy my first "real" rust hobby project i put out there is getting used and people are commenting on it. now i get a whole new class of people to disappoint with my programming hey congrats!
|
|
# ? Sep 25, 2017 02:33 |
|
Powerful Two-Hander posted:ok I've got a fresh blank slate graduate minion who knows no SQL, what's the least bad resource for teaching them poo poo? if they have like a CS background you could have them read the original EF Codd paper about the relational model. i read it as an undergrad and i remember it still being super readable even though some of its terminology now sounds old-fashioned. a warning here is that if they read it then go hog wild learning relational algebra, you might have to bring them down back to earth about how joins work in the real world Lutha Mahtin fucked around with this message at 03:45 on Sep 25, 2017 |
# ? Sep 25, 2017 03:08 |
|
LinYutang posted:Opengl is truly hell open graphics library is not a programming language hope this helps
|
# ? Sep 25, 2017 04:00 |
|
hey we did it, 3-dimensional transformation on the jaguar the matrix multiplication isn't done on the GPU yet though... here it is with a transparent object in front of it courtesy of my broken font rendering
|
# ? Sep 25, 2017 04:02 |
|
serious question: why does exception handling performance matter?
|
# ? Sep 25, 2017 04:07 |
|
gonadic io posted:oh boy my first "real" rust hobby project i put out there is getting used and people are commenting on it. now i get a whole new class of people to disappoint with my programming that's great!
|
# ? Sep 25, 2017 04:15 |
|
Shinku ABOOKEN posted:serious question: why does exception handling performance matter? because it makes using exceptions for flow control a better or worse idea
|
# ? Sep 25, 2017 04:22 |
|
Shinku ABOOKEN posted:serious question: why does exception handling performance matter? the cost of actually throwing an exception matters if you need to throw an exception. if the overhead of throwing an exception is very high — because it allocates a lot of memory, or runs a lot of dormant code, or just takes a long time — then you have to take that into account when writing code whose performance matters but even if you never throw an exception, the language implementation generally has to make sure that, if you had, it would have worked. in many languages, that is a pervasive cost, even in functions that don't do anything explicit with exceptions. depending on the language implementation, this might add a lot of code (most of it dormant), or introduce a lot of dynamic checks, or require a lot of dynamic bookkeeping. sometimes this can be controlled or eliminated, e.g. by promising to never throw an exception dynamically; otherwise, it's just an overhead you have to live with, unless you can change language implementations, and you may need to find ways to ameliorate it in the code whose performance matters of course if none of your code's performance matters, then nothing that affects your code's performance matters
|
# ? Sep 25, 2017 04:52 |
|
oh and of course it matters to people either implementing or trying to exploit the implementation of a language
|
# ? Sep 25, 2017 05:04 |
|
eschaton posted:open graphics library is not a programming language glsl and arb are though
|
# ? Sep 25, 2017 05:31 |
|
i hate it when there's some computer science word that i dont understand and it scares me and then i finally learn what it means and it's simple today's word is isomorphic
|
# ? Sep 25, 2017 06:20 |
|
it basically just means "equal" (not identity, but value equality)
|
# ? Sep 25, 2017 07:55 |
MALE SHOEGAZE posted:i hate it when there's some computer science word that i dont understand and it scares me and then i finally learn what it means and it's simple
|
|
# ? Sep 25, 2017 07:56 |
|
EDIT: nevermind
|
# ? Sep 25, 2017 08:58 |
|
lancemantis posted:same but for virtuaboys I managed to get a Virtual Boy during the firesale in 1997, along with several games, it was pretty cool it doesn't work now because of the display connection adhesive breakdown problem from which they all suffer, but theoretically it should just be a matter of re-positioning and re-adhering it I wonder what all the hardware was capable of that nobody got to try
|
# ? Sep 25, 2017 09:10 |
|
rjmccall posted:this is mostly spot-on but i want to clarify that libUnwind also supports resumable exceptions and so also does a two-phase search. in fact that's also required with non-resumable exceptions for compatibility reasons, because for whatever reason throwing an exception without a handler historically hasn't actually unwound the stack before calling std::terminate (the c++ standard allows this, it's unspecified). we had problems with that in llvm for awhile because we were trying to emit destructors in a way that made the frame essentially catch and rethrow, and that's not actually semantically correct yeah that's how I thought it worked too! rjmccall posted:also unlike the windows unwinder, libUnwind basically isn't allowed to have any persistent state during unwind. this is because it doesn't have any persistent stack storage — it only has stack frames during calls to _Unwind_RaiseException or _Unwind_Resume, which it has to exit in order to enter a function to run cleanups or handlers — and the only persistent heap storage it gets is the exception object, which can be thrown multiple times simultaneously because of std::exception_ptr. so e.g. it can't remember anything it learned during the search phase and use that when unwinding, or at least it has to degrade cleanly when the exception object becomes shared isn't there an extra argument that's passed around, other than the exception pointer? or am I remembering wrong btw how is your support for windows exceptions nowadays? a long time ago I even downloaded the clang source code to see if I could do something but I have to lol at myself and my naivety because - leaving aside how complex a compiler frontend is - it turned out that (iirc) libunwind exceptions are baked in llvm itself
|
# ? Sep 25, 2017 11:02 |
|
gonadic io posted:oh boy my first "real" rust hobby project i put out there is getting used and people are commenting on it. now i get a whole new class of people to disappoint with my programming cool. what does it do??
|
# ? Sep 25, 2017 11:29 |
|
You'll never find out. If it's cool enough that people are commenting on it then he probably doesn't want to be associating it/himself with some dead gay Goatse and Beecock Internet Forum.
|
# ? Sep 25, 2017 11:40 |
|
my stepdads beer posted:cool. what does it do?? https://github.com/djmcgill/form it separates out nested inline modules into the proper directory structure. so takes one big auto generated file (in my case generated using svd2rust) and turns it into the proper "form" to use as an actual library mostly it's just a little script that im using to learn how rust logging/deploying/error handling works, it's real overkill for a lovely little file manip like that ToadStyle posted:You'll never find out. If it's cool enough that people are commenting on it then he probably doesn't want to be associating it/himself with some dead gay Goatse and Beecock Internet Forum. im very out on this forum gonadic io fucked around with this message at 12:03 on Sep 25, 2017 |
# ? Sep 25, 2017 11:49 |
|
Powaqoatse posted:it basically just means "equal" (not identity, but value equality) isn't isomorphic usually used in the category theory sense in computer science? ie `f(g(x, y)) = g(f(x), f(y))` or i guess you could be talking about the dumb as poo poo 'isomorphic javascript' usage
|
# ? Sep 25, 2017 16:07 |
|
yes. it means there's a back-and-forth correspondence that preserves all relevant structure. so the informal sense is "functionally the same as, even if there's some unimportant difference"
|
# ? Sep 25, 2017 16:17 |
|
hackbunny posted:isn't there an extra argument that's passed around, other than the exception pointer? or am I remembering wrong yeah, so before the unwinder re-enters a frame (at a "landing pad" instruction mentioned in the unwind table), it first sets a couple of registers that act as parameters to the landing pad. one of these is just the exception pointer, and the other is a "selector" value which tells the landing pad why it's been re-entered. if you have C++ code:
when a function is re-entered just to run cleanups, it's not allowed to just return, it has to eventually call _Unwind_Resume (assuming it doesn't just abort or spin). _Unwind_Resume doesn't care about the selector value, it's just going to keep unwinding out of this function. it's not technically illegal for the call to _Unwind_Resume to itself have unwind actions in the current function but it probably means something went wrong in the compiler because landing-pad chaining doesn't work that way: you need the unwind table entries for the original call to accurately describe everything that the function might do in response to the exception, because otherwise the unwinder has the right to completely skip the function. that means that e.g. inlining has to be smart about landing pads and vice-versa conversely, when a function is re-entered to handle an exception, it's not allowed to call _Unwind_Resume, it has to eventually actually handle the exception (which involves calling back into libUnwind) and then maybe re-throw it while it's being handled note that if a function just has handlers that don't apply to the exception, it never gets re-entered at all also note that a lot of what i just said is not actually about libUnwind itself. the exception tables for a function come in two parts, the part interpreted directly by libUnwind is just some primitive information about the stack frame and then a pointer to a "personality function" that knows how to interpret the rest of the table. it's the personality function that decides whether it needs to re-enter a function and is charge of conventions like writing the exception pointer and selector into certain registers. basically libUnwind passes it the frame's saved register state, and the personality messes with that and then tells libUnwind whether it should resume here or keep going hackbunny posted:btw how is your support for windows exceptions nowadays? a long time ago I even downloaded the clang source code to see if I could do something but I have to lol at myself and my naivety because - leaving aside how complex a compiler frontend is - it turned out that (iirc) libunwind exceptions are baked in llvm itself for c++ exceptions, it's pretty good, but yeah, we ended with basically two completely different eh representations on the two platforms. the people working on it really wanted to use a common representation but ultimately decided that the requirements were just too different. e.g. it's a lot harder to optimize code using windows exceptions because the c++ runtime expects cleanups to be structured in a very fiddly way, or so they tell me for seh i think it's still pretty hand-wavey because llvm ir does not have any way to represent that a load or store or divide can start an unwind
|
# ? Sep 25, 2017 18:11 |
|
hell yeah i generate rotation matrices on the 26MHz jaguar dsp now instead of the 13MHz 68k it's pretty slow though for some reason, probably because i'm not good at writing code for weird one-off risc architectures
|
# ? Sep 26, 2017 02:41 |
|
Writing Fast GPU and DSP Programs posted:Wait states are incurred when: hmm, probably shouldn't do this to fill a matrix then code:
|
# ? Sep 26, 2017 02:45 |
|
|
# ? May 26, 2024 04:08 |
|
rjmccall posted:yeah, so before the unwinder re-enters a frame (at a "landing pad" instruction mentioned in the unwind table), it first sets a couple of registers that act as parameters to the landing pad. one of these is just the exception pointer, and the other is a "selector" value which tells the landing pad why it's been re-entered. quote:_Unwind_SetGR oooh now I get what you meant rjmccall posted:also note that a lot of what i just said is not actually about libUnwind itself. the exception tables for a function come in two parts, the part interpreted directly by libUnwind is just some primitive information about the stack frame and then a pointer to a "personality function" that knows how to interpret the rest of the table. it's the personality function that decides whether it needs to re-enter a function and is charge of conventions like writing the exception pointer and selector into certain registers. basically libUnwind passes it the frame's saved register state, and the personality messes with that and then tells libUnwind whether it should resume here or keep going sure, SEH works exactly the same. I have written my own personality functions for SEH frames rjmccall posted:e.g. it's a lot harder to optimize code using windows exceptions because the c++ runtime expects cleanups to be structured in a very fiddly way, or so they tell me well, for one, you have to make a closure around all variables that might be affected by an unwind visual c++ on x86 elegantly sidesteps the issue by just loading the original ebp lol. or do you mean you actually use msvcrt (and its abi) on windows and you have to structure code exactly like visual c++ because I figure at some point it must be simply less effort to just write your own libc (fake edit: yep you do hats off, that's no mean feat) rjmccall posted:for seh i think it's still pretty hand-wavey because llvm ir does not have any way to represent that a load or store or divide can start an unwind I hadn't realized that clang never had -fasynchronous-exceptions. scratch my earlier "all major compilers" then
|
# ? Sep 26, 2017 14:50 |