3 ms·
Can you expand on the concept of throwing/catching to warm up? I’ve never heard of that before (though I’m also not remotely familiar with C++).
by bryancoxwell 2y ago
Can you expand on the concept of throwing/catching to warm up? I’ve never heard of that before (though I’m also not remotely familiar with C++).
- achierius 2y agoGenerally warming up caches (l1i, l1d, l2, ...) and other hardware state (e.g. out-of-order engine) so that you get a better picture of how your program will run in the steady state, rather than how it will perform on the first iteration with 'cold caches'. The justification for this is that in most (but not all) software applications, you should expect a reasonable amount of spatial/temporal locality and thus for your caches to be useful. So the 'average' performance of your program would be best captured by how the program runs when 'warm'. Warm -> populated with the code/data your program uses. Cold -> empty, or filled with stuff your program doesn't use. I do think that the case of exception handling is one where I would question the validity of this approach: if you catch exceptions rarely, it's quite reasonable to expect that the relevant lines would have been conflict'ed out of your l1i at some point in the interim, and therefore that the l1i (or even l2!) fetch cost is reasonable to include in the benchmark. However, if you expect your exceptions to fire 'relatively often' then it again becomes reasonable to warm up the caches before measuring, so it really comes down to the characteristics of your workload.
- jart 2y agoI'm just teasing out the one-time costs. Keep in mind, I'm using the above example to trace the libc/libc++/libcxxabi/libunwind runtimes. The first time you throw, it does a bunch of extra stuff, like getenv() and additional locking. I think the first throw needs about thirteen synchronization barriers total.