5 ms·
Yup, and to complement, a very important technique is to design platform-specific layers such that they call the (portable) application code - not the other way
by jstimpfle 5y ago
Yup, and to complement, a very important technique is to design platform-specific layers such that they call the (portable) application code - not the other way around. The more typical approach is attempting to find abstractions for I/O and other platform specific facilities that can be implemented by all targeted platforms. The issue with that is that it is very hard to really make use of the platform this way, or even implement all abstractions for all platforms without quirks. If instead the platform layer calls the (un-abstracted) portable application code, there is no code that needs to be pushed through misfitting abstractions.
I learned this approach from Handmade Here / Handmade Community and it's probably the deepest architectural lesson I learned anywhere, while it seems to be not widely known. I'm almost tempted to say that the conventional approach is wrong and misguided. However, an issue with the platform-calls-code approach is that the code usually can only communicate asynchronously with the platform (one of the issues with code-calls-platform is the one-shot synchronous nature of function calls). That might not work always, for example, I wanted RDTSC counters or Copy-Paste functionality, and I still do this by finding a platform abstraction that the code can call into directly.
- dundarious 5y agoI know RDTSC was just an example, but I really wouldn't worry about going Platform->App->Platform for features that have no architectural concerns or impact (in this case, some number connected to performance, probably a cycle count, that's monotonically increasing). I/O would be the major no-no.
- jstimpfle 5y agoI agree on that point. To extend, I said RDTSC but was actually thinking of QueryPerformanceCounter() (my bad). Going App->Platform becomes problematic when an abstracted facility cannot be implemented as a simple function call but requires a "protocol" that involves multiple function calls. QueryPerformanceCounter() is a simple case here, it only requires an initialization step using QueryPerformanceFrequency(), but it could already be seen as an absraction leak. Either that, or the abstraction has to be designed to include calls and data structures that are only used on certain implementations. This requires foresight when designing the abstraction and it makes the abstraction inconvenient to use.
- dundarious 5y agoYes, maybe something requires some setup in the top Platform layer, but QPC is also pretty light on that front. And you should only apply the frequency when displaying the value for humans anyway, which makes it quite easy to wrangle the values from QPC and CLOCK_MONOTONIC, etc., at the display site, IME.
- deleted 5y ago[deleted]