5 ms·
At this point, when I see libraries like this all I can think is ”oh good, my compile times aren’t long enough, lets make EVERY INTEGER a template”. Also, whil
by OskarS 7y ago
At this point, when I see libraries like this all I can think is ”oh good, my compile times aren’t long enough, lets make EVERY INTEGER a template”.
Also, while I can reasonably beliveve that most of the overhead goes away at -O2 or -O3, this has to just trash performance for debug builds, which is not unimportant.
- std_throwaway 7y agoIt does not change your existing integers or compilation time. Only where you use the new types the compiler will have more work to do. What would be the alternative in those places? Manual code? Preprocessor macros? Assertions everywhere? A theorem prover? To me the implementation seems to be a good solution given that you don't want to change the core language.
- q3k 7y ago> What would be the alternative in those places? Fix the damn language.
- netheril96 7y agoAs in, adding more features to C++? And then people cry about how complex C++ is.
- byuu 7y agoStop worrying about 9-bit bytes, only logical shift right for signed integers, ones-complement and sign-bit integers, etc and define this stuff in the standard. PDP-11 was a long time ago. C++20 is heading in the right direction with defining twos-complement. The next good step would be declaring signed overflow as wrapping (eg -fwrapv)
- smitty1e 7y agoAnd if the application's run-time safety requirements demand that the debug performance hit be paid, then that audience will view the debug sluggishness as a cost of doing business. Welcome to engineering tradeoffs.
- andrepd 7y agoHave you measured? Also, what do you mean by "this has to just trash performance for debug builds". Do you mean runtime performance?
- OskarS 7y agoYes, that’s what I mean. And before you say ”debug performance doesn’t matter”: yes it does. I work in gamedev and it’s a huge problem that C++ has such awful debug performance, because it’s hard to debug a game if it’s running in single-digit framerates. It’s a large part of the reason why EASTL is so popular in gamedev.
- ntauthority 7y agoSingle-level inlining helps a lot with that but any libraries that do more calls that should be inlined are still a pain (and it reduces your debugging ability with, say, lambdas in VS at least).
- jancsika 7y ago> single-digit framerates In more explicit terms-- you are a soft-realtime app developer trying to live in a world that rarely measures performance or even writes specs with your constraints in mind. I wish you game devs would harp on this more. I'm just a lowly soft-realtime audio software dev. My voice doesn't carry because there aren't mountains of cash behind me to help echo it.
- muststopmyths 7y agooh it's been harped on for years. But people with mountains of cash already wrote their own STL and heap allocators :-) Those are usually your main bottlenecks in usability of debug builds. I've worked on games with "DebugOptimized" builds where it's optimized,but instrumented in other ways. That's probably the best solution. You only drop down to full debug if you absolutely can't debug a specific issue in an optimized build. With Visual C++, if you are careful you can build a version with release runtimes and third party libs so only your code is debug. Microsoft makes it harder than it has to be though.
- kurtisc 7y agoHigh level languages are sold on the concept that customers' machines are powerful enough that the reduction in performance is worth it for the reduction in development time. For the same reason, it should be worthwhile to give developers powerful machines so they spend less time fixing runtime bugs.
- deleted 7y ago[deleted]
- pjmlp 7y agoGiven that many of the security features did run perfectly fine in 60's hardware, I think they can manage in 21st century machines. "Many years later we asked our customers whether they wished us to provide an option to switch off these checks in the interests of efficiency on production runs. Unanimously, they urged us not to--they already knew how frequently subscript errors occur on production runs where failure to detect them could be disastrous. I note with fear and horror that even in 1980, language designers and users have not learned this lesson. In any respectable branch of engineering, failure to observe such elementary precautions would have long been against the law." -- Tony Hoare, "The 1980 ACM Turing Award Lecture"
- flatline 7y agoRight - boost::units is supposed to be a zero-overhead abstraction buy there are still edge cases where the compiler can’t optimize away all the template wrappings. Generally still worth it, if you find a performance bottleneck you can move back to doubles and conventions to keep the units straight. This sounds like it may not be so easy to selectively opt out of.
- banachtarski 7y agoI don't think you even looked at the library, but from I can tell, debug perf would not be impacted at all.
- OskarS 7y agoOf course it will be impacted. Libraries like these are "zero-cost" only because of very aggressive inlining (not generally available in debug builds), otherwise all its operations happen in subroutines. Operator overloading is the most obvious example: for regular integers, addition is basically a single instruction even in debug, but with a library like this, it has to make a subroutine call. A call which has who knows how many layers of abstraction that compiler optimizations hasn't shaken off. In fact, the README says as much: it has only zero time/space overhead "assuming basic compiler optimizations like inlining". And I did actually look at the code, but at a glance I couldn't get much sense of it. The main header imports like two dozen other headers, and the "detail" folder is filled to the brim with more headers. I tried cloning and using it, but I couldn't get it to compile (which is probably mostly my fault, but I really didn't want to spend too much time on it). I did run just the preprocessor though, and "#include <bounded/integer.hpp>" expanded to 48000 lines. 48000 extra lines to compile in order to use integers. For every file you use it in. I don't want to be too harsh here, I'm sure it's an excellent library and it does what it says brilliantly, and if you need bounded integers I'm sure it's awesome. But language like "[integers in C++] are mostly unusable" rankles a bit, and the the implication in this file is that this is something you should regularly use instead of integer types. I personally feel that libraries like this are taking C++ in the wrong direction ("ranges" is another obvious example) and making the language less and less usable in my profession.
- banachtarski 7y ago> but with a library like this, it has to make a subroutine call. I mean, before I wrote my comment I checked and it's `constexpr` all the way down to the add instruction so if it's going to make a call, I'm not seeing it. There is definitely a lot of template machinery, but I can't be the judge of that immediately. > I personally feel that libraries like this are taking C++ in the wrong direction ("ranges" is another obvious example) I think you're making an emotional argument based on some preconceived twitter-verse sentiment. I'm in games too (graphics specifically) and people are up and arms about the wrong thing. Maybe there are corner cases that are a bit overly complex, but what's wrong with being able to write `std::sort(container)` instead of `std::sort(container.begin, container.end)`. There may be things we don't like, but I don't think we should resort to hyperbole either. Incidentally, I wouldn't use this library if only because for what I do, having explicitly sized data types is important.
- deleted 7y ago[deleted]
- byuu 7y agoIn my line of software work, I needed variable-precision integers (think uint5_t, uint13_t, etc) to express details of the architecture cleanly and avoid lots of manual bit-masking, which naturally meant having to use templates. I found that it didn't really hurt compile times much (500KLOC compiles in about 40 seconds with make -j on a 16-core box), and performance is just barely impacted at -O2, but it definitely destroys debug build performance completely and makes a mess of code profiling and backtrace debugging output. There are also all kinds of subtle gotchas: you can make "x ? y : z" work when y and z are different primitive types, but not if one is a template. You cannot make them work with printf("%d", x) directly (it compiles fine and then you run into problems), etc. Trying to enforce stronger type checking (not allowing the implicit mixing of signed and unsigned, etc) introduces endless worlds of pain and ambiguous operator overload problems. Trying to make eg "x++" or "x+y" return another template instance instead of a primitive type similarly causes a world of pain everywhere. I still feel it was 100% worth it in my case, but it has many pitfalls. Taking it even further to bounding to specific ranges as this library aims to do feels even more fraught with danger. I do not envy the work of its authors.
- nybble41 7y ago> You cannot make them work with printf("%d", x) directly (it compiles fine and then you run into problems), etc. To be fair that's also true for standard intN_t or uintN_t types. "%d" expects an int argument, and while several of the intN_t types may be converted to int by the default argument type promotion rules, that isn't guaranteed. For example, while plain "%d" works for int64_t on ILP64 platforms with 64-bit int values, LP64 (32-bit int, 64-bit long) requires "%ld" and 32-bit platforms require "%lld". That's why you have e.g. the PRId64 macro from <inttypes.h> to select the correct format code for printing int64_t values. You could provide something similar to abstract away the required format code. If you're using the GNU C library you can even define custom format codes with register_printf_function(), which might be your only option if the calling convention for your template doesn't match any of the standard integer types.
- davidstone 7y agoLibrary author here: As I have added more features to the library, compile times have definitely suffered. Fortunately, the latest version of the clang compiler added `-ftime-trace`, which reports where the compiler spends its time. I am currently going through and optimizing the compile-time performance of my library. However, I expect the largest gain to come in the next year or so once compilers + build systems implement C++20 modules so that you don't have to compile everything every time you use it. For run-time performance, yes, you definitely get a hit in your run time if you have all optimizations off. However, I have found that the practical benefits of things like this library, combined with run-time sanitizers, is worth much more at finding bugs than a debugger, so I typically debug and develop with `-O3 -fsanitize=undefined -fsanitize=address` and release mode is `-O3 -flto=thin -DNDEBUG`. This is an area where it's not possible (yet) to satisfy all use cases. I am hopeful that in the future, it will be much easier to tell your compiler "this is the code I care about debugging, optimize the rest".