Why do execution times drop so drastically with increasing number of iterations? Shouldn’t the caches be filled after one iteration already? There is no JIT in C++, or is it?
I only had a quick look at the code, but it looks like it's timing memory allocation. For example the sprintf part uses std::string str(100, '\0'). I'm not a C++ expert, but I believe this is essentially doing a malloc and memset of 100 bytes for every call to sprintf. So this is probably a poorly setup benchmark.
Formatting text in C++: Old and new ways
61–70 of 73 posts
Re: Formatting text in C++: Old and new ways
#62It seems so trite, especially in 2023, but please don't use sprintf. It isn't safe in general. (Even snprintf is tricky.)
Disagree. Use whatever is the most simple and boring option for the problem's solution.
Also, the standard library has so much stuff that will give you pain in runtime, that avoiding sprintf really is not relevant.
I don't know what "Safe" means in general in the scope of C++. If there is a memory corruption, my program will crash. Then I will compile it with C++ debug runtime, which will pinpoint the exact location that caused the memory leak. Then I fix the leak.
Not using sprintf will not result in code that would not have memory leaks. C++ in total is unsafe. You need to write code and have production system that foremost takes this into account. You can't make C++ safe by following dogma of not using functions with possible side-effects. There is a very hight chance your fall-back algorithms themselves will leak memroy anyway.
The only way to write 'as non-leaky' C++ as possible is to make the code as simple, and easy to reason about as possible, and to have tooling to assist in program validation. This requirement is much more important than avoiding some parts of standard library.
Use static checkers, use Microsoft's debug C runtime, use address sanitizers, etc.
If you know some parts of you standard library are broken then ofc avoid them. But what can be considered "broken" really depends what one is trying to achiece, and which platforms one is targeting.
Re: Formatting text in C++: Old and new ways
#63Why do execution times drop so drastically with increasing number of iterations? Shouldn’t the caches be filled after one iteration already? There is no JIT in C++, or is it?
> There is no JIT in C++, or is it? This question doesn't make sense for the context*. C++ is Ahead of Time, by design; there is nothing to "just in time" compile. JIT (as a concept) only makes sense if you are, in some way, abstracting your code from native machine code (usually via some sort of VM, like Python or Java's), which the "system" languages (C, Rust, Zig, C++, etc) do not. What I think you are trying to r…
Can I talk to you about our Lord and Savior the CPU trace cache[1]?
That is to say, I know next to nothing about how modern CPUs are actually designed and hardly more about JITs, but a modern CPU’s frontend with a microop cache sure looks JITy to me. The trace cache on NetBurst looks even more classically JITy, but by itself it was a miserable failure, so meh.
In any event, a printf invocation seems like it should be too large for the cache to come into play;—on the other hand, all the predictors learning stuff over the iterations might make a meaningful impact?
Seems to me like that learning, if present, would make the benchmark less interesting, not more, as an actual prospective application of string formatting seems unlikely to go through formatting the same (kind of) thing and nothing else in a tight loop.
[1] https://chipsandcheese.com/2022/06/17/intels-netburst-failur...
Re: Formatting text in C++: Old and new ways
#64Earlier quoted context omitted.
> There is no JIT in C++, or is it? This question doesn't make sense for the context*. C++ is Ahead of Time, by design; there is nothing to "just in time" compile. JIT (as a concept) only makes sense if you are, in some way, abstracting your code from native machine code (usually via some sort of VM, like Python or Java's), which the "system" languages (C, Rust, Zig, C++, etc) do not. What I think you are trying to r…
> C++ is Ahead of Time, by design; there is nothing to "just in time" compile. Can I talk to you about our Lord and Savior the CPU trace cache[1]? That is to say, I know next to nothing about how modern CPUs are actually designed and hardly more about JITs, but a modern CPU’s frontend with a microop cache sure looks JITy to me. The trace cache on NetBurst looks even more classically JITy, but by itself it was a miser…
Re: Formatting text in C++: Old and new ways
#65Why do execution times drop so drastically with increasing number of iterations? Shouldn’t the caches be filled after one iteration already? There is no JIT in C++, or is it?
Your CPU is effectively a virtual machine with stuff like branch prediction, speculative execution w/rollback, pipelining, implicit parallelism, etc. etc. Of course, it isn't able to do quite as much as a VM running in software (because fixed buffers for everything, etc.), but even so...
Re: Formatting text in C++: Old and new ways
#66Re: Formatting text in C++: Old and new ways
#67Why do execution times drop so drastically with increasing number of iterations? Shouldn’t the caches be filled after one iteration already? There is no JIT in C++, or is it?
Re: Formatting text in C++: Old and new ways
#68It seems so trite, especially in 2023, but please don't use sprintf. It isn't safe in general. (Even snprintf is tricky.)
There are a lot of use cases where "isn't safe" is absolutely irrelevant
Re: Formatting text in C++: Old and new ways
#69Earlier quoted context omitted.
> There is no JIT in C++, or is it? This question doesn't make sense for the context*. C++ is Ahead of Time, by design; there is nothing to "just in time" compile. JIT (as a concept) only makes sense if you are, in some way, abstracting your code from native machine code (usually via some sort of VM, like Python or Java's), which the "system" languages (C, Rust, Zig, C++, etc) do not. What I think you are trying to r…
> C++ is Ahead of Time, by design; there is nothing to "just in time" compile. Can I talk to you about our Lord and Savior the CPU trace cache[1]? That is to say, I know next to nothing about how modern CPUs are actually designed and hardly more about JITs, but a modern CPU’s frontend with a microop cache sure looks JITy to me. The trace cache on NetBurst looks even more classically JITy, but by itself it was a miser…
This is clearly not what the OP was asking about.
Re: Formatting text in C++: Old and new ways
#70Earlier quoted context omitted.
> C++ is Ahead of Time, by design; there is nothing to "just in time" compile. Can I talk to you about our Lord and Savior the CPU trace cache[1]? That is to say, I know next to nothing about how modern CPUs are actually designed and hardly more about JITs, but a modern CPU’s frontend with a microop cache sure looks JITy to me. The trace cache on NetBurst looks even more classically JITy, but by itself it was a miser…
If you want to muddy the waters for contrarianism, go for it. This is clearly not what the OP was asking about.
No, and I don’t appreciate the accusation.
> This is clearly not what the OP was asking about.
Eh. I thought this was on topic when I wrote. On a second read I’m not sure either way. In any case, my point stands, I think: there are things happening that warm up after multiple loop iterations, as characteristic of JITs and not caches, and one potential source of those things is in fact JITish despite the fact that the translation of C++ into x86-64 has nothing to do with it—even if I’m not sure whether this is the right explanation in this particular case. The general answer to “can JITish things happen to my C++ code” is a definite yes.