Skip to content

Instantly share code, notes, and snippets.

@andrewrk
Created January 8, 2016 13:31
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andrewrk/ac66b24a0a202d87cea7 to your computer and use it in GitHub Desktop.
Save andrewrk/ac66b24a0a202d87cea7 to your computer and use it in GitHub Desktop.
conversation about fast int types in #musl irc channel
[16:00:47] <andrewrk> in practice, are the int_fastN_t types worth using?
[16:01:04] <andrewrk> what about cache performance?
[16:01:26] <nsz> no but it has nothing to do with technical reasons
[16:01:40] <andrewrk> go on?
[16:02:26] <nsz> the standard failed to clearly specify the intent of these types (is it for fast storage access, arithmetics,..?)
[16:03:00] <nsz> and the consequence is that implementations (glibc/gcc) made horrible choices (int_fast16_t is 64bit on 64bit machines)
[16:03:08] <andrewrk> ugh
[16:03:24] <andrewrk> well I'm playing with a toy language / compiler and I'm thinking about integer types
[16:03:24] <nsz> so a int_fast16_t division is much slower than an int16_t one
[16:03:36] <andrewrk> so what if we were to toss out the spec and imagine it better?
[16:04:47] <andrewrk> it seems to make sense that when you were going to declare an integer, you would use a type that has "at least N bits" unless you were trying to make a packed struct or have a specific bit requirement
[16:05:14] <nsz> yes, that's int_least32_t
[16:05:26] <andrewrk> ahh
[16:05:41] <andrewrk> so, I guess, I would repeat the question for int_leastN_t -
[16:05:52] <andrewrk> in practice, are those types worth using/
[16:05:53] <andrewrk> ?
[16:06:15] <nsz> yes, because they are guaranteed while int32_t is not guaranteed to be defined
[16:06:30] <nsz> (int32_t must be 32bit, int_least32_t does not have to be)
[16:06:55] <andrewrk> what about using int_least32_t et all in a dynamic library?
[16:07:09] <andrewrk> is there a potential problem with that?
[16:07:16] <nsz> (in practice nobody cares, but standards do care so it can come up)
[16:07:48] <pikhq> I suspect the main intent of the int_fastN_t types is for certain bizarre systems where some of the types have *especially* slow implementations.
[16:08:04] <pikhq> e.g. think int8_t on a system that can only do arithmetic on 32-bit ints.
[16:08:12] <XgF> Arithmetic on 32-bit ints is fine
[16:08:27] <pikhq> s/arithmetic/any operations/
[16:08:34] <XgF> But think crappy old RISC architectures (e.g. really old ARMv2) where theres no 8/16-bit memory loads
[16:09:04] <XgF> The problem with int_fastN_t is that its an alias of some "basic" type
[16:09:12] <nsz> andrewrk: i'd avoid using weird types in public interfaces
[16:09:20] <nsz> that makes life easier usually
[16:09:27] <andrewrk> I'm imagining a type, which is defined to be at least N bits, and then is the smallest size integer that has register-native arithmetic
[16:09:29] <XgF> When really fastest is "it depends"... and largely compilers can optimize int_leastN_t/intN_t just as well
[16:09:40] <XgF> andrewrk: "register native"?
[16:09:47] *** Quits: BitL0G1c (~BitL0G1c@97e7e3f2.skybroadband.com) (Ping timeout: 264 seconds)
[16:09:49] <nsz> if you target a posix platform it's perfectly fine to use int{8,16,32,64}_t types
[16:09:55] <andrewrk> XgF, for example it doesn't have to bit mask and shift to get the answer
[16:10:11] <andrewrk> nsz, can you think of any specific problems with using weird types in public interfaces?
[16:10:19] <nsz> oh of course
[16:10:20] <XgF> andrewrk: I can't think of any type where int_fastN_t != intN_t on any reasonable/modern architecture
[16:10:24] <XgF> by that definition
[16:10:40] <nsz> eg musl abi is different than glibc one for some weird types :)
[16:10:53] <nsz> you can run into similar issues with ffi
[16:11:06] <andrewrk> XgF, what about pikhq's example of a system that only has 32-bit arithmetic
[16:11:11] <nsz> (other languages try to call into your library that uses weird types)
[16:11:19] <pikhq> andrewrk: "Reasonable/modern".
[16:11:26] <andrewrk> ah, right.
[16:11:33] <pikhq> It's a hypothetical, not a common consideration anymore. :)
[16:11:40] <XgF> andrewrk: That includes most non-x86 systems. In practice 16/8-bit arithmetic is at best as fast as 32 on x86 which does have it, and sometimes slower
[16:11:44] <nsz> (this historically caused lot of problems.. when python/perl/.. runtimes try to guess the right definition of socklen_t etc)
[16:11:57] <XgF> (the one exception on x86 is that 8/16-bit divs are faster than 32)
[16:12:16] <andrewrk> what about embedded development?
[16:12:41] <XgF> andrewrk: For 8-bit embedded platforms invariably intN_t==int_fastN_t if the ABI is well designed
[16:12:50] <andrewrk> interesting
[16:12:50] <XgF> For 32-bit, uh, "reasonable/modern" applies
[16:13:03] <XgF> andrewrk: And remember that the complier is instantly going to promote any sub-int arithmetic to int
[16:13:03] <andrewrk> so really, intN_t is the way to go.
[16:13:37] <XgF> The one exception is that int_fastN_t where defined == int/unsigned int probably gives the compiler more optimization leeway in general
[16:14:53] <XgF> (you eliminate some zext/sexting where unused upper bits could shift in over asignment boundries)
[16:15:07] <andrewrk> interesting.
[16:15:32] <andrewrk> well, thanks for your input, this is all very informative
[16:15:45] <XgF> Defining them to be 64-bit like glibc is pretty stupid since every 64-bit arch worth a damn has good 32-bit arithmetic support
[16:16:01] <andrewrk> right
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment