Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #79727 > unrolled thread
| Started by | Lynn McGuire <lynnmcguire5@gmail.com> |
|---|---|
| First post | 2021-05-24 20:46 -0500 |
| Last post | 2021-06-01 17:35 -0700 |
| Articles | 20 on this page of 112 — 21 participants |
Back to article view | Back to comp.lang.c++
recovering from std::bad_alloc in std::string reserve Lynn McGuire <lynnmcguire5@gmail.com> - 2021-05-24 20:46 -0500
Re: recovering from std::bad_alloc in std::string reserve Lynn McGuire <lynnmcguire5@gmail.com> - 2021-05-24 20:50 -0500
Re: recovering from std::bad_alloc in std::string reserve Lynn McGuire <lynnmcguire5@gmail.com> - 2021-05-24 20:52 -0500
Re: recovering from std::bad_alloc in std::string reserve Paavo Helde <myfirstname@osa.pri.ee> - 2021-05-25 07:47 +0300
Re: recovering from std::bad_alloc in std::string reserve Lynn McGuire <lynnmcguire5@gmail.com> - 2021-05-25 12:20 -0500
Re: recovering from std::bad_alloc in std::string reserve Christian Gollwitzer <auriocus@gmx.de> - 2021-05-26 08:36 +0200
Re: recovering from std::bad_alloc in std::string reserve Lynn McGuire <lynnmcguire5@gmail.com> - 2021-05-26 13:28 -0500
Re: recovering from std::bad_alloc in std::string reserve Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-25 12:56 +0200
Re: recovering from std::bad_alloc in std::string reserve scott@slp53.sl.home (Scott Lurndal) - 2021-05-25 14:55 +0000
Re: recovering from std::bad_alloc in std::string reserve Paavo Helde <myfirstname@osa.pri.ee> - 2021-05-25 18:42 +0300
Re: recovering from std::bad_alloc in std::string reserve MrSpook_Ann1u@d0v_5eh1bqgd.com - 2021-05-25 16:10 +0000
Re: recovering from std::bad_alloc in std::string reserve Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-25 18:23 +0200
Re: recovering from std::bad_alloc in std::string reserve Paavo Helde <myfirstname@osa.pri.ee> - 2021-05-25 19:57 +0300
Re: recovering from std::bad_alloc in std::string reserve MrSpook_ddZgr4t4@okc9_pd48oig5.info - 2021-05-26 07:15 +0000
Re: recovering from std::bad_alloc in std::string reserve Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-26 09:22 +0200
Re: recovering from std::bad_alloc in std::string reserve Paavo Helde <myfirstname@osa.pri.ee> - 2021-05-26 10:54 +0300
Re: recovering from std::bad_alloc in std::string reserve MrSpook_dw5lvA4g@kak0_42x.edu - 2021-05-26 08:29 +0000
Re: recovering from std::bad_alloc in std::string reserve Nikolaj Lazic <nlazicBEZ_OVOGA@mudrac.ffzg.hr> - 2021-05-25 16:21 +0000
Re: recovering from std::bad_alloc in std::string reserve Paavo Helde <myfirstname@osa.pri.ee> - 2021-05-25 20:04 +0300
Re: recovering from std::bad_alloc in std::string reserve Lynn McGuire <lynnmcguire5@gmail.com> - 2021-05-25 12:46 -0500
Re: recovering from std::bad_alloc in std::string reserve Paavo Helde <myfirstname@osa.pri.ee> - 2021-05-25 20:58 +0300
Re: recovering from std::bad_alloc in std::string reserve Lynn McGuire <lynnmcguire5@gmail.com> - 2021-05-25 13:48 -0500
Re: recovering from std::bad_alloc in std::string reserve Nikolaj Lazic <nlazicBEZ_OVOGA@mudrac.ffzg.hr> - 2021-05-25 18:23 +0000
Re: recovering from std::bad_alloc in std::string reserve Lynn McGuire <lynnmcguire5@gmail.com> - 2021-05-25 13:49 -0500
Re: recovering from std::bad_alloc in std::string reserve Lynn McGuire <lynnmcguire5@gmail.com> - 2021-05-26 21:07 -0500
Re: recovering from std::bad_alloc in std::string reserve Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-25 18:23 +0200
Re: recovering from std::bad_alloc in std::string reserve Lynn McGuire <lynnmcguire5@gmail.com> - 2021-05-24 22:33 -0500
Re: recovering from std::bad_alloc in std::string reserve Lynn McGuire <lynnmcguire5@gmail.com> - 2021-05-24 22:35 -0500
Re: recovering from std::bad_alloc in std::string reserve Juha Nieminen <nospam@thanks.invalid> - 2021-05-25 05:16 +0000
Re: recovering from std::bad_alloc in std::string reserve Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-25 13:00 +0200
Re: recovering from std::bad_alloc in std::string reserve Lynn McGuire <lynnmcguire5@gmail.com> - 2021-05-25 12:49 -0500
Re: recovering from std::bad_alloc in std::string reserve Lynn McGuire <lynnmcguire5@gmail.com> - 2021-05-27 14:08 -0500
Re: recovering from std::bad_alloc in std::string reserve scott@slp53.sl.home (Scott Lurndal) - 2021-05-27 21:59 +0000
Re: recovering from std::bad_alloc in std::string reserve Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-05-27 15:33 -0700
Re: recovering from std::bad_alloc in std::string reserve Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-05-27 15:58 -0700
Re: recovering from std::bad_alloc in std::string reserve Lynn McGuire <lynnmcguire5@gmail.com> - 2021-05-27 18:17 -0500
Re: recovering from std::bad_alloc in std::string reserve Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-05-27 16:58 -0700
Re: recovering from std::bad_alloc in std::string reserve Öö Tiib <ootiib@hot.ee> - 2021-05-27 18:36 -0700
Re: recovering from std::bad_alloc in std::string reserve Lynn McGuire <lynnmcguire5@gmail.com> - 2021-05-27 21:38 -0500
Re: recovering from std::bad_alloc in std::string reserve Paavo Helde <myfirstname@osa.pri.ee> - 2021-05-28 08:53 +0300
Re: recovering from std::bad_alloc in std::string reserve Bo Persson <bo@bo-persson.se> - 2021-05-28 09:47 +0200
Re: recovering from std::bad_alloc in std::string reserve Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-05-27 19:54 -0700
Re: recovering from std::bad_alloc in std::string reserve Öö Tiib <ootiib@hot.ee> - 2021-05-27 21:02 -0700
Re: recovering from std::bad_alloc in std::string reserve Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-05-28 12:09 -0700
Re: recovering from std::bad_alloc in std::string reserve scott@slp53.sl.home (Scott Lurndal) - 2021-05-28 20:26 +0000
Re: recovering from std::bad_alloc in std::string reserve Öö Tiib <ootiib@hot.ee> - 2021-05-28 17:10 -0700
Re: recovering from std::bad_alloc in std::string reserve David Brown <david.brown@hesbynett.no> - 2021-05-29 11:47 +0200
Re: recovering from std::bad_alloc in std::string reserve "daniel...@gmail.com" <danielaparker@gmail.com> - 2021-05-30 15:15 -0700
Re: recovering from std::bad_alloc in std::string reserve David Brown <david.brown@hesbynett.no> - 2021-05-31 08:33 +0200
Re: recovering from std::bad_alloc in std::string reserve "daniel...@gmail.com" <danielaparker@gmail.com> - 2021-05-31 08:21 -0700
Re: recovering from std::bad_alloc in std::string reserve David Brown <david.brown@hesbynett.no> - 2021-05-31 18:13 +0200
Re: recovering from std::bad_alloc in std::string reserve Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-05-31 14:43 -0700
Re: recovering from std::bad_alloc in std::string reserve Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-05-31 14:44 -0700
Re: recovering from std::bad_alloc in std::string reserve "daniel...@gmail.com" <danielaparker@gmail.com> - 2021-05-31 15:20 -0700
Re: recovering from std::bad_alloc in std::string reserve Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-06-01 11:17 -0700
Re: recovering from std::bad_alloc in std::string reserve Manfred <noname@add.invalid> - 2021-06-01 20:25 +0200
Re: recovering from std::bad_alloc in std::string reserve Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-06-01 16:55 -0700
Re: recovering from std::bad_alloc in std::string reserve David Brown <david.brown@hesbynett.no> - 2021-06-02 09:06 +0200
Re: recovering from std::bad_alloc in std::string reserve Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-06-05 17:50 -0700
Re: recovering from std::bad_alloc in std::string reserve David Brown <david.brown@hesbynett.no> - 2021-06-06 11:10 +0200
Re: recovering from std::bad_alloc in std::string reserve Öö Tiib <ootiib@hot.ee> - 2021-06-06 04:07 -0700
Re: recovering from std::bad_alloc in std::string reserve Richard Damon <Richard@Damon-Family.org> - 2021-06-06 07:49 -0400
Re: recovering from std::bad_alloc in std::string reserve Manfred <noname@add.invalid> - 2021-06-01 20:21 +0200
Re: recovering from std::bad_alloc in std::string reserve David Brown <david.brown@hesbynett.no> - 2021-06-02 09:29 +0200
Re: recovering from std::bad_alloc in std::string reserve Manfred <noname@add.invalid> - 2021-06-02 18:43 +0200
Re: recovering from std::bad_alloc in std::string reserve David Brown <david.brown@hesbynett.no> - 2021-06-02 23:32 +0200
Re: recovering from std::bad_alloc in std::string reserve Manfred <noname@add.invalid> - 2021-06-03 00:49 +0200
Re: recovering from std::bad_alloc in std::string reserve David Brown <david.brown@hesbynett.no> - 2021-06-03 09:08 +0200
Re: recovering from std::bad_alloc in std::string reserve David Brown <david.brown@hesbynett.no> - 2021-06-03 10:53 +0200
Re: recovering from std::bad_alloc in std::string reserve Manfred <noname@add.invalid> - 2021-06-03 16:20 +0200
Re: recovering from std::bad_alloc in std::string reserve James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-06-03 11:20 -0400
Re: recovering from std::bad_alloc in std::string reserve David Brown <david.brown@hesbynett.no> - 2021-06-03 19:04 +0200
Re: recovering from std::bad_alloc in std::string reserve scott@slp53.sl.home (Scott Lurndal) - 2021-06-03 22:24 +0000
Re: recovering from std::bad_alloc in std::string reserve Öö Tiib <ootiib@hot.ee> - 2021-06-03 16:27 -0700
Re: recovering from std::bad_alloc in std::string reserve scott@slp53.sl.home (Scott Lurndal) - 2021-06-04 00:36 +0000
Re: recovering from std::bad_alloc in std::string reserve David Brown <david.brown@hesbynett.no> - 2021-06-04 08:46 +0200
Re: recovering from std::bad_alloc in std::string reserve Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-06-05 22:02 -0700
Re: recovering from std::bad_alloc in std::string reserve David Brown <david.brown@hesbynett.no> - 2021-06-06 11:17 +0200
Re: recovering from std::bad_alloc in std::string reserve Manfred <noname@add.invalid> - 2021-06-06 18:39 +0200
Re: recovering from std::bad_alloc in std::string reserve Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-06-06 16:33 -0700
Re: recovering from std::bad_alloc in std::string reserve David Brown <david.brown@hesbynett.no> - 2021-06-07 08:41 +0200
Re: recovering from std::bad_alloc in std::string reserve David Brown <david.brown@hesbynett.no> - 2021-06-06 17:46 +0200
Re: recovering from std::bad_alloc in std::string reserve MrSpook_Qfmtjdmi@nc6.com - 2021-06-06 14:11 +0000
Re: recovering from std::bad_alloc in std::string reserve Manfred <noname@add.invalid> - 2021-06-03 16:43 +0200
Re: recovering from std::bad_alloc in std::string reserve Manfred <noname@add.invalid> - 2021-06-01 18:00 +0200
Re: recovering from std::bad_alloc in std::string reserve David Brown <david.brown@hesbynett.no> - 2021-06-01 19:15 +0200
Re: recovering from std::bad_alloc in std::string reserve David Brown <david.brown@hesbynett.no> - 2021-06-01 15:55 +0200
Re: recovering from std::bad_alloc in std::string reserve Bo Persson <bo@bo-persson.se> - 2021-06-01 13:59 +0200
Re: recovering from std::bad_alloc in std::string reserve Lynn McGuire <lynnmcguire5@gmail.com> - 2021-06-01 13:26 -0500
Re: recovering from std::bad_alloc in std::string reserve David Brown <david.brown@hesbynett.no> - 2021-06-01 08:29 +0200
Re: recovering from std::bad_alloc in std::string reserve Bo Persson <bo@bo-persson.se> - 2021-06-01 14:05 +0200
Re: recovering from std::bad_alloc in std::string reserve David Brown <david.brown@hesbynett.no> - 2021-06-01 15:58 +0200
Re: recovering from std::bad_alloc in std::string reserve James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-06-01 11:33 -0400
Re: recovering from std::bad_alloc in std::string reserve Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-06-01 10:52 -0700
Re: recovering from std::bad_alloc in std::string reserve James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-05-27 23:16 -0400
Re: recovering from std::bad_alloc in std::string reserve scott@slp53.sl.home (Scott Lurndal) - 2021-05-28 14:34 +0000
Re: recovering from std::bad_alloc in std::string reserve Lynn McGuire <lynnmcguire5@gmail.com> - 2021-05-27 18:19 -0500
Re: recovering from std::bad_alloc in std::string reserve Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-28 03:47 +0200
Re: recovering from std::bad_alloc in std::string reserve Lynn McGuire <lynnmcguire5@gmail.com> - 2021-05-27 17:45 -0500
Re: recovering from std::bad_alloc in std::string reserve scott@slp53.sl.home (Scott Lurndal) - 2021-05-28 14:38 +0000
Re: recovering from std::bad_alloc in std::string reserve Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-28 16:44 +0200
Re: recovering from std::bad_alloc in std::string reserve Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-28 16:42 +0200
Re: recovering from std::bad_alloc in std::string reserve Paavo Helde <myfirstname@osa.pri.ee> - 2021-05-28 18:22 +0300
Re: recovering from std::bad_alloc in std::string reserve Paavo Helde <myfirstname@osa.pri.ee> - 2021-05-28 08:47 +0300
Re: recovering from std::bad_alloc in std::string reserve Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-26 06:16 +0200
Re: recovering from std::bad_alloc in std::string reserve Lynn McGuire <lynnmcguire5@gmail.com> - 2021-05-26 13:30 -0500
Re: recovering from std::bad_alloc in std::string reserve Bonita Montero <Bonita.Montero@gmail.com> - 2021-05-26 20:37 +0200
Re: recovering from std::bad_alloc in std::string reserve Lynn McGuire <lynnmcguire5@gmail.com> - 2021-05-26 14:09 -0500
Re: recovering from std::bad_alloc in std::string reserve "Alf P. Steinbach" <alf.p.steinbach@gmail.com> - 2021-05-26 18:33 +0200
Re: recovering from std::bad_alloc in std::string reserve Lynn McGuire <lynnmcguire5@gmail.com> - 2021-05-26 13:32 -0500
Re: recovering from std::bad_alloc in std::string reserve Christian Gollwitzer <auriocus@gmx.de> - 2021-05-27 07:50 +0200
Re: recovering from std::bad_alloc in std::string reserve "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-06-01 17:35 -0700
Page 4 of 6 — ← Prev page 1 2 3 [4] 5 6 Next page →
| From | Öö Tiib <ootiib@hot.ee> |
|---|---|
| Date | 2021-06-06 04:07 -0700 |
| Message-ID | <f9f7fade-0113-4680-bab0-3117b8ea6502n@googlegroups.com> |
| In reply to | #80179 |
On Sunday, 6 June 2021 at 12:10:59 UTC+3, David Brown wrote: > On 06/06/2021 02:50, Keith Thompson wrote: > > <snipping for brevity - as usual, you make good points, but I don't > think I have much to add> > > I disagree. intmax_t has not turned out to be a useful as it was > > intended to be, but it's hardly useless. > > > Fair enough. You've convinced me that it has some future-proofing uses, > even if such future-proofing may never be needed in practice. > (Predictions about the future are always hard.) From my own viewpoint, > it looks like the unintended consequences outweigh the usefulness, but > my viewpoint is not the only one! But it is very interesting topic. I think that future goes towards more enforced safety like Rust is doing on one hand and more flexibility about properties (like bit width of integers) on other hand. So adding or subtracting two int_t<8> will simply result with int_t<9> and intmax_t stops making sense whatsoever since int_t<512> takes one cache line and int_t<1024> two, but otherwise no difference from int_t<9>.
[toc] | [prev] | [next] | [standalone]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2021-06-06 07:49 -0400 |
| Message-ID | <PC2vI.29779$431.11271@fx39.iad> |
| In reply to | #80179 |
On 6/6/21 5:10 AM, David Brown wrote: > On 06/06/2021 02:50, Keith Thompson wrote: > > <snipping for brevity - as usual, you make good points, but I don't > think I have much to add> > >> I disagree. intmax_t has not turned out to be a useful as it was >> intended to be, but it's hardly useless. >> > > Fair enough. You've convinced me that it has some future-proofing uses, > even if such future-proofing may never be needed in practice. > (Predictions about the future are always hard.) From my own viewpoint, > it looks like the unintended consequences outweigh the usefulness, but > my viewpoint is not the only one! > I think the issue that wasn't anticipated was the longevity of an ABI that used the type intmax_t. intmax_t makes it easier to move a program from one ABI to another with different sizes of integer types. It unfortunately locks in the biggest type that a given ABI will handle.
[toc] | [prev] | [next] | [standalone]
| From | Manfred <noname@add.invalid> |
|---|---|
| Date | 2021-06-01 20:21 +0200 |
| Message-ID | <s95trr$1bna$1@gioia.aioe.org> |
| In reply to | #80030 |
On 6/1/2021 7:15 PM, David Brown wrote: > On 01/06/2021 18:00, Manfred wrote: >> On 6/1/2021 3:55 PM, David Brown wrote: >>> On 01/06/2021 13:59, Bo Persson wrote: >>>> On 2021-06-01 at 00:20, daniel...@gmail.com wrote: >>>>> On Monday, May 31, 2021 at 5:43:23 PM UTC-4, Keith Thompson wrote: >>>>>> David Brown <david...@hesbynett.no> writes: >>>>>>> On 31/05/2021 00:15, daniel...@gmail.com wrote: >>>>>>>> On Saturday, May 29, 2021 at 5:47:50 AM UTC-4, David Brown wrote: >>>>>>>>> The definition of intmax_t is a problem - it is a limitation for >>>>>>>>> integer >>>>>>>>> types in C and C++. Hopefully eventually deprecate intmax_t. >>>>>>>> >>>>>>>> One proposal is to make intmax_t mean int64_t, and leave it at that. >>>>>>>> Have no requirement that integer types can't be larger. No more ABI >>>>>>>> problem. >>>>>>> >>>>>>> It might make more sense to tie it to "long long int" rather than >>>>>>> "int64_t", but someone would first have to check if it affected any >>>>>>> real >>>>>>> implementations before making such a change. But yes, that might be a >>>>>>> way out and a way forward. >>>>>> [...] >>>>>> >>>>>> That would allow intmax_t to be 128 bits on implementations with >>>>>> 128-bit long long (are there any?), which seems like a good idea. >>>>>> >>>>>> I think the point of both these proposals is purely for backward >>>>>> compatibility, avoiding breaking code that already uses [u]intmax_t. >>>>>> Both of them destroy the point of intmax_t, providing a type that's >>>>>> guaranteed to be the longest integer type. Should intmax_t be >>>>>> deprecated? >>>>>> >>>>> Yes. "Give me the biggest integer type there is" is not a reasonable >>>>> thing to ask for, in any code that is intended to be portable across >>>>> platforms >>>>> or over time on the same platform. You may as well have intwhatever_t. >>>>> >>>> >>>> The problem is that we in general don't know what "whatever" is. At the >>>> time when intmax_t was introduced, at least in C there were >>>> implementations with 36 bit ints and 72-bit longs. So just using int64_t >>>> would not be portable. >>>> >>> >>> Have there ever been C99 compilers for 36-bit int machines? Were there >>> even conforming C90 compilers? >>> >>> AFAIK (and I fully admit my knowledge may be lacking), the only systems >>> that made it past the 1980's which did not have two's complement signed >>> integers with 8-bit bytes and power-of-two sized integer types are some >>> DSPs and other niche embedded devices (for which no one would use an >>> integer type without knowing /exactly/ how big it is), and >>> Burroughs/Unisys systems for legacy compatibility. >>> >>> My suggestion would be to lock intmax_t to "long long", which would keep >>> compatibility here (including for systems that have 128-bit long long, >>> if there are any other than a hypothetical RISC-V version). >>> >>> >>> >> >> I think this would be problematic as well, or at least useless and >> confusing. >> The idea for intmax_t is to give a standard name to the widest integer >> type that is available, which is by definition implementation defined. >> Having intmax_t an alias for "long long" would change its meaning to the >> widest /standard/ integer type defined by the standard itself - a >> useless repetition (we have "long long" for that), and confusing too, >> given its change in meaning. > > Yes, that is all true. The point is not to find another useful purpose > for intmax_t - the point is to get rid of it, marking it as deprecated, > but to do so in a way that won't break existing code. > > I am at a loss to understand why anyone would have a use for intmax_t in > the first place. The use I see is with imaxdiv and friends as I wrote below, at least this is my understanding. When would you want an integer type whose sole > characteristic is "big" ? To me, it is logical to want a type that is > at least N bits, or exactly N bits. These requirements are covered by > the normal "short", "int", "long" and "long long" types, or - better for > my use, but not necessarily other people's - the <stdint.h> fixed size > types. "intmax_t" gives you absolutely /nothing/ that "long long" does not. > > Given that there are, as far as we know, no implementations where > intmax_t does not correspond directly to "long long", I would like to > see "intmax_t" be dropped to the maximum extent allowable by backwards > compatibility. > >> >> As far as I understand the purpose for intmax_t is to allow for (sort >> of) 'standard' prototypes of functions like imaxabs, imaxdiv, strtoimax, >> etc that are supposed to operate on larger integer types - these are the >> only functions that take this kind of arguments. >> The confusing part is that all of these facilities are implementation >> dependent, so even if they are part of the standard they are /not/ >> portable, meaning that the programmer is supposed (the way I see it) to >> use them under the guard of appropriate preprocessor directives. >> >> The use for them is to allow the programmer to use some optimized >> routines for larger types, if available. > > But they don't allow that. If you are trying to make optimised routines > for larger types, you need to know your sizes - you either use > implementation extensions (like __int128), or fixed size types, or if > you need maximal portability, you use "int_fast64_t". When I wrote "use" I didn't mean "make". I meant imaxdiv may be a 128 bit division routine provided by the implementation that the programmer can to use without the need to write one, possible a less efficient one. > >> >> For example, in case operations like ldiv are needed on 128 bit >> integers, then IF the implementation supports 128 bit intmax_t then >> imaxdiv can be a better choice rather than implementing your own routine >> - note that /IF/ is the keyword here, that should map directly to >> appropriate #if directives. >> > > The situation we have now is that on a compiler like gcc you can get > 128-bit division using __int128, but /not/ using intmax_t. It is a > useless type. > The way I see it this is a problem with gcc, not with the standard. Unless the committee managed to produce some wording that is too problematic for __int128 to fit as extended integer type. Note that I am not talking about plain integer division (the '/' operator) I am talking about 128 bit ldiv. Now we have div, ldiv and lldiv too (supposedly for 64 bit), but instead of going on with llldiv, and then llllllllldiv, they decided to stop with imaxdiv. It makes sense. >> It's most probably somewhat a niche field of use (possibly growing due >> to the diffuse demand for cryptography), or meant for applications that >> are supposed to be run on hardware that is known to support the >> appropriate types, so that the #if directives can be as simple as >> denying compilation for implementations that don't have a wide enough >> intmax_t. >> >> My 2c. >
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2021-06-02 09:29 +0200 |
| Message-ID | <s97c05$7fh$1@dont-email.me> |
| In reply to | #80046 |
On 01/06/2021 20:21, Manfred wrote: > On 6/1/2021 7:15 PM, David Brown wrote: >> On 01/06/2021 18:00, Manfred wrote: >>> As far as I understand the purpose for intmax_t is to allow for (sort >>> of) 'standard' prototypes of functions like imaxabs, imaxdiv, strtoimax, >>> etc that are supposed to operate on larger integer types - these are the >>> only functions that take this kind of arguments. >>> The confusing part is that all of these facilities are implementation >>> dependent, so even if they are part of the standard they are /not/ >>> portable, meaning that the programmer is supposed (the way I see it) to >>> use them under the guard of appropriate preprocessor directives. >>> >>> The use for them is to allow the programmer to use some optimized >>> routines for larger types, if available. >> >> But they don't allow that. If you are trying to make optimised routines >> for larger types, you need to know your sizes - you either use >> implementation extensions (like __int128), or fixed size types, or if >> you need maximal portability, you use "int_fast64_t". > > When I wrote "use" I didn't mean "make". I meant imaxdiv may be a 128 > bit division routine provided by the implementation that the programmer > can to use without the need to write one, possible a less efficient one. > On gcc, "imaxdiv" lets you divide 64-bit numbers. If x and y are type __int128, then "x / y" lets you divide 128-bit numbers. The "div" functions give you /nothing/ in a modern compiler. They are a hangover from the bad old days where "x = a / b; y = a % b;" could not be handled efficiently by compiler. The "imaxdiv" function must be the most useless function ever specified - indeed, it is worse than useless because it interferes with changing or removing intmax_t. (I appreciate why it was introduced - I'm writing with hindsight that the C99 authors did not have.) >> >>> >>> For example, in case operations like ldiv are needed on 128 bit >>> integers, then IF the implementation supports 128 bit intmax_t then >>> imaxdiv can be a better choice rather than implementing your own routine >>> - note that /IF/ is the keyword here, that should map directly to >>> appropriate #if directives. >>> >> >> The situation we have now is that on a compiler like gcc you can get >> 128-bit division using __int128, but /not/ using intmax_t. It is a >> useless type. >> > > The way I see it this is a problem with gcc, not with the standard. > Unless the committee managed to produce some wording that is too > problematic for __int128 to fit as extended integer type. Keith has given some replies here. There is nothing in the standards that would have prevented gcc making __int128 as an extended integer type when C99 was introduced. The problem is that the definition of intmax_t makes it extremely difficult to /change/ the type, and therefore to /introduce/ a new larger extended integer type at a later date. Once the ABI for a platform has been decided, intmax_t is fixed and no larger integer types can be introduced without change and disruption that is well out of proportion for the gains. > > Note that I am not talking about plain integer division (the '/' > operator) I am talking about 128 bit ldiv. > Now we have div, ldiv and lldiv too (supposedly for 64 bit), but instead > of going on with llldiv, and then llllllllldiv, they decided to stop > with imaxdiv. It makes sense. > Perhaps I am missing something. What do the div functions give you that the division operators do not (assuming an optimising compiler) ?
[toc] | [prev] | [next] | [standalone]
| From | Manfred <noname@add.invalid> |
|---|---|
| Date | 2021-06-02 18:43 +0200 |
| Message-ID | <s98ceu$1rbv$1@gioia.aioe.org> |
| In reply to | #80074 |
On 6/2/2021 9:29 AM, David Brown wrote: > On 01/06/2021 20:21, Manfred wrote: >> On 6/1/2021 7:15 PM, David Brown wrote: [...] >>> >>> The situation we have now is that on a compiler like gcc you can get >>> 128-bit division using __int128, but /not/ using intmax_t. It is a >>> useless type. >>> >> >> The way I see it this is a problem with gcc, not with the standard. >> Unless the committee managed to produce some wording that is too >> problematic for __int128 to fit as extended integer type. > > Keith has given some replies here. > > There is nothing in the standards that would have prevented gcc making > __int128 as an extended integer type when C99 was introduced. The > problem is that the definition of intmax_t makes it extremely difficult > to /change/ the type, and therefore to /introduce/ a new larger extended > integer type at a later date. Once the ABI for a platform has been > decided, intmax_t is fixed and no larger integer types can be introduced > without change and disruption that is well out of proportion for the gains. > Technically, this is still a problem of the implementation, not of the standard. Granted, implementations and the standard have a long history of going along together, but still they are different things and they work at different levels. I believe you and Keith (his link is indeed instructive) when you say that there are ABI problems with intmax_t, but I am not convinced that they are absolutely objective - I may think there is some weight of the legacy of ABI definitions as they have been structured for decades. After all, in C passing arguments of varying type is not a new issue - structs have been part of the ABI since the beginning of time. It seems more likely to me that the drive to solve this issue is not strong enough because of the limited range of cases where this is really needed. As I wrote earlier the real need is probably somewhat for a niche area. >> >> Note that I am not talking about plain integer division (the '/' >> operator) I am talking about 128 bit ldiv. >> Now we have div, ldiv and lldiv too (supposedly for 64 bit), but instead >> of going on with llldiv, and then llllllllldiv, they decided to stop >> with imaxdiv. It makes sense. >> > > Perhaps I am missing something. What do the div functions give you that > the division operators do not (assuming an optimising compiler) ? > I assume you mean the division /and/ remainder operators. Obviously the div functions give both formally in one operation, taking advantage of the ASM instructions that do that. I know that most optimizing compilers are able to combine a sequence of '/' and '%' into a single instruction, but this is relying on optimization, and thus not standardized. I now we are probably going to disagree on this point, but to me it is relevant that some feature, if it is important to the program, be possible to express in source code with no need to assume some behind-the-scenes compiler behavior. More importantly, in this last point I took the div functions as one example, in fact there is a whole family of those, ranging from abs to strtol, and even printf that are involved with intmax_t.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2021-06-02 23:32 +0200 |
| Message-ID | <s98tdn$6qc$1@dont-email.me> |
| In reply to | #80100 |
On 02/06/2021 18:43, Manfred wrote:
> On 6/2/2021 9:29 AM, David Brown wrote:
>> On 01/06/2021 20:21, Manfred wrote:
>>> On 6/1/2021 7:15 PM, David Brown wrote:
> [...]
>>>>
>>>> The situation we have now is that on a compiler like gcc you can get
>>>> 128-bit division using __int128, but /not/ using intmax_t. It is a
>>>> useless type.
>>>>
>>>
>>> The way I see it this is a problem with gcc, not with the standard.
>>> Unless the committee managed to produce some wording that is too
>>> problematic for __int128 to fit as extended integer type.
>>
>> Keith has given some replies here.
>>
>> There is nothing in the standards that would have prevented gcc making
>> __int128 as an extended integer type when C99 was introduced. The
>> problem is that the definition of intmax_t makes it extremely difficult
>> to /change/ the type, and therefore to /introduce/ a new larger extended
>> integer type at a later date. Once the ABI for a platform has been
>> decided, intmax_t is fixed and no larger integer types can be introduced
>> without change and disruption that is well out of proportion for the
>> gains.
>>
>
> Technically, this is still a problem of the implementation, not of the
> standard. Granted, implementations and the standard have a long history
> of going along together, but still they are different things and they
> work at different levels.
> I believe you and Keith (his link is indeed instructive) when you say
> that there are ABI problems with intmax_t, but I am not convinced that
> they are absolutely objective - I may think there is some weight of the
> legacy of ABI definitions as they have been structured for decades.
Legacy and ABI definitions are definitely the issues here, and
technically these are part of the implementation, rather than the
standard. The way the standard defines intmax_t makes it very
impractical (but not impossible) for implementations to provide larger
integer types. I see that as a problem or limitation in the standard,
rather than an implementation issue.
> After all, in C passing arguments of varying type is not a new issue -
> structs have been part of the ABI since the beginning of time.
>
Yes, but structs (and arrays) are defined in terms of existing scaler
types. ABI's generally do not specify how to pass larger integer types
- it is not covered by the specification for a struct comprising of two
smaller types.
> It seems more likely to me that the drive to solve this issue is not
> strong enough because of the limited range of cases where this is really
> needed. As I wrote earlier the real need is probably somewhat for a
> niche area.
>
That seems reasonable.
>>>
>>> Note that I am not talking about plain integer division (the '/'
>>> operator) I am talking about 128 bit ldiv.
>>> Now we have div, ldiv and lldiv too (supposedly for 64 bit), but instead
>>> of going on with llldiv, and then llllllllldiv, they decided to stop
>>> with imaxdiv. It makes sense.
>>>
>>
>> Perhaps I am missing something. What do the div functions give you that
>> the division operators do not (assuming an optimising compiler) ?
>>
>
> I assume you mean the division /and/ remainder operators.
Yes.
> Obviously the div functions give both formally in one operation, taking
> advantage of the ASM instructions that do that.
A compiler will usually do that two, given "x = a / b; y = a % b;". On
many processors, a single division instruction produces both results and
compilers will take advantage of that.
When I did a few tests on <https://godbolt.org>, compilers generated
calls to library "div" functions when these were given in the source
code, and direct cpu division instructions for the division and
remainder operators. I must admit it surprised me a little - I'd have
thought the "div" functions would be handled as builtins. But they are
not on the list of gcc "Other builtins" ("abs" is, as are a great many
other standard library functions). I guess the developers simply
haven't bothered - perhaps because the "div" functions are rarely used.
Certainly the operators give simpler and clearer source code, and
significantly smaller and faster object code in practice.
> I know that most optimizing compilers are able to combine a sequence of
> '/' and '%' into a single instruction, but this is relying on
> optimization, and thus not standardized.
The same could be said about calling "div" - the standard does not give
any indication that it is implemented in any particularly efficient way.
Most likely, it is done by :
div_t div(int a, int b) {
div_t d;
d.quot = a / b;
d.rem = a % b;
return d;
}
> I now we are probably going to disagree on this point, but to me it is
> relevant that some feature, if it is important to the program, be
> possible to express in source code with no need to assume some
> behind-the-scenes compiler behavior.
>
I don't disagree on that principle at all. But I /do/ disagree about
any assumptions you make about how "div" is implemented, and that it has
any required behaviour or guarantees that you don't get from the operators.
> More importantly, in this last point I took the div functions as one
> example, in fact there is a whole family of those, ranging from abs to
> strtol, and even printf that are involved with intmax_t.
The "abs" function family does not need an "intmax_t" specific version -
it could be handled by the <tgmath.h> "abs" generic macro. (That's for
C - for C++, you'd prefer a template.)
Some of the other functions taking or returning an "intmax_t" would add
complications, yes. That's why "intmax_t" would need to be deprecated
rather than just dropped.
[toc] | [prev] | [next] | [standalone]
| From | Manfred <noname@add.invalid> |
|---|---|
| Date | 2021-06-03 00:49 +0200 |
| Message-ID | <s991ul$1hca$1@gioia.aioe.org> |
| In reply to | #80116 |
On 6/2/2021 11:32 PM, David Brown wrote:
> On 02/06/2021 18:43, Manfred wrote:
>> On 6/2/2021 9:29 AM, David Brown wrote:
>>> On 01/06/2021 20:21, Manfred wrote:
>>>> On 6/1/2021 7:15 PM, David Brown wrote:
>> [...]
>>>>
>>>> Note that I am not talking about plain integer division (the '/'
>>>> operator) I am talking about 128 bit ldiv.
>>>> Now we have div, ldiv and lldiv too (supposedly for 64 bit), but instead
>>>> of going on with llldiv, and then llllllllldiv, they decided to stop
>>>> with imaxdiv. It makes sense.
>>>>
>>>
>>> Perhaps I am missing something. What do the div functions give you that
>>> the division operators do not (assuming an optimising compiler) ?
>>>
>>
>> I assume you mean the division /and/ remainder operators.
>
> Yes.
>
>> Obviously the div functions give both formally in one operation, taking
>> advantage of the ASM instructions that do that.
>
> A compiler will usually do that two, given "x = a / b; y = a % b;". On
> many processors, a single division instruction produces both results and
> compilers will take advantage of that.
>
> When I did a few tests on <https://godbolt.org>, compilers generated
> calls to library "div" functions when these were given in the source
> code, and direct cpu division instructions for the division and
> remainder operators. I must admit it surprised me a little - I'd have
> thought the "div" functions would be handled as builtins. But they are
> not on the list of gcc "Other builtins" ("abs" is, as are a great many
> other standard library functions). I guess the developers simply
> haven't bothered - perhaps because the "div" functions are rarely used.
Interesting, that's surprising.
> Certainly the operators give simpler and clearer source code, and
> significantly smaller and faster object code in practice.
>
'Certainly' smaller and faster because you tested it. As per their
definition, there is no reason for which div should perform worse than
'/' and '%'.
In fact, the only motivation for the *div functions to exist is that
they perform better, or at the very least equal, to the pair '/' and '%'.
To me it sounds like a matter of QoI.
>> I know that most optimizing compilers are able to combine a sequence of
>> '/' and '%' into a single instruction, but this is relying on
>> optimization, and thus not standardized.
>
> The same could be said about calling "div" - the standard does not give
> any indication that it is implemented in any particularly efficient way.
> Most likely, it is done by :
>
> div_t div(int a, int b) {
> div_t d;
> d.quot = a / b;
> d.rem = a % b;
> return d;
> }
>
>
>> I now we are probably going to disagree on this point, but to me it is
>> relevant that some feature, if it is important to the program, be
>> possible to express in source code with no need to assume some
>> behind-the-scenes compiler behavior.
>>
>
> I don't disagree on that principle at all. But I /do/ disagree about
> any assumptions you make about how "div" is implemented, and that it has
> any required behaviour or guarantees that you don't get from the operators.
>
Well, it's the /definition/ of "div" that it calculates the quotient and
the remainder in one go, not an assumption.
In this specific case, the same applies to performance: as I said it is
the only reason for it to exist.
If the implementation is sloppy then it's good to know, but it's also a
different matter.
>> More importantly, in this last point I took the div functions as one
>> example, in fact there is a whole family of those, ranging from abs to
>> strtol, and even printf that are involved with intmax_t.
>
> The "abs" function family does not need an "intmax_t" specific version -
> it could be handled by the <tgmath.h> "abs" generic macro. (That's for
> C - for C++, you'd prefer a template.)
>
> Some of the other functions taking or returning an "intmax_t" would add
> complications, yes. That's why "intmax_t" would need to be deprecated
> rather than just dropped.
>
>
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2021-06-03 09:08 +0200 |
| Message-ID | <s99v4j$jqj$1@dont-email.me> |
| In reply to | #80117 |
On 03/06/2021 00:49, Manfred wrote:
> On 6/2/2021 11:32 PM, David Brown wrote:
>> On 02/06/2021 18:43, Manfred wrote:
>>> On 6/2/2021 9:29 AM, David Brown wrote:
>>>> On 01/06/2021 20:21, Manfred wrote:
>>>>> On 6/1/2021 7:15 PM, David Brown wrote:
>>> [...]
>>>>>
>>>>> Note that I am not talking about plain integer division (the '/'
>>>>> operator) I am talking about 128 bit ldiv.
>>>>> Now we have div, ldiv and lldiv too (supposedly for 64 bit), but
>>>>> instead
>>>>> of going on with llldiv, and then llllllllldiv, they decided to stop
>>>>> with imaxdiv. It makes sense.
>>>>>
>>>>
>>>> Perhaps I am missing something. What do the div functions give you
>>>> that
>>>> the division operators do not (assuming an optimising compiler) ?
>>>>
>>>
>>> I assume you mean the division /and/ remainder operators.
>>
>> Yes.
>>
>>> Obviously the div functions give both formally in one operation, taking
>>> advantage of the ASM instructions that do that.
>>
>> A compiler will usually do that two, given "x = a / b; y = a % b;". On
>> many processors, a single division instruction produces both results and
>> compilers will take advantage of that.
>>
>> When I did a few tests on <https://godbolt.org>, compilers generated
>> calls to library "div" functions when these were given in the source
>> code, and direct cpu division instructions for the division and
>> remainder operators. I must admit it surprised me a little - I'd have
>> thought the "div" functions would be handled as builtins. But they are
>> not on the list of gcc "Other builtins" ("abs" is, as are a great many
>> other standard library functions). I guess the developers simply
>> haven't bothered - perhaps because the "div" functions are rarely used.
>
> Interesting, that's surprising.
>
Yes. While I don't expect the "div" functions to be much used, it seems
to me it should a relatively easy optimisation.
(MSVC manages it, gcc, clang and icc do not.)
>> Certainly the operators give simpler and clearer source code, and
>> significantly smaller and faster object code in practice.
>>
>
> 'Certainly' smaller and faster because you tested it.
The cleaner and simpler source code is the "certainly" part. I am sure
there are some older or more limited compilers for targets without
hardware division and for which calling the "div" function is more
efficient. (Testing gcc on targets like the AVR that don't have
division assembly instructions, basically the same code was generated
for "div" and /, % .)
> As per their
> definition, there is no reason for which div should perform worse than
> '/' and '%'.
The function call overhead here is going to dominate the cost -
shuffling around data into the right registers, calling the function in
a library (imagine if it is in a DLL/so), instruction cache misses,
stacking and restoring other data according to ABI volatile and
preserved register usage, reduced scope for optimisation with constant
propagation, inlining, pre-calculating results, etc. There are many
reasons why it should be worse.
> In fact, the only motivation for the *div functions to exist is that
> they perform better, or at the very least equal, to the pair '/' and '%'.
> To me it sounds like a matter of QoI.
>
I am sure that in the early days of C, the div functions would - on some
systems at least - have performed better than the division operators
together. But not now - and not for a long time, on most targets.
>>> I know that most optimizing compilers are able to combine a sequence of
>>> '/' and '%' into a single instruction, but this is relying on
>>> optimization, and thus not standardized.
>>
>> The same could be said about calling "div" - the standard does not give
>> any indication that it is implemented in any particularly efficient way.
>> Most likely, it is done by :
>>
>> div_t div(int a, int b) {
>> div_t d;
>> d.quot = a / b;
>> d.rem = a % b;
>> return d;
>> }
>>
>>
>>> I now we are probably going to disagree on this point, but to me it is
>>> relevant that some feature, if it is important to the program, be
>>> possible to express in source code with no need to assume some
>>> behind-the-scenes compiler behavior.
>>>
>>
>> I don't disagree on that principle at all. But I /do/ disagree about
>> any assumptions you make about how "div" is implemented, and that it has
>> any required behaviour or guarantees that you don't get from the
>> operators.
>>
>
> Well, it's the /definition/ of "div" that it calculates the quotient and
> the remainder in one go, not an assumption.
The wording is "in a single operation". Since that concept is not
explicitly defined in the standard (AFAIK), and since there is no way
that standard can insist that a particular implementation does the
operation as a single instruction (not all processors have division
instructions of any sort), that part of the description simply says you
get both results from one function call.
> In this specific case, the same applies to performance: as I said it is
> the only reason for it to exist.
> If the implementation is sloppy then it's good to know, but it's also a
> different matter.
On most modern processors, no implementation could possibly have a
library call here that is faster than doing the operations using / and %
with a single division assembly code. It's not being sloppy - it is
impossible. You'd have to go out of your way to make an intentially
poor quality compiler for a call to "div" to be faster than using the
operators. (Failing to replace the "div" call with inline code is a
missed optimisation opportunity, and therefore QoI.)
>
>>> More importantly, in this last point I took the div functions as one
>>> example, in fact there is a whole family of those, ranging from abs to
>>> strtol, and even printf that are involved with intmax_t.
>>
>> The "abs" function family does not need an "intmax_t" specific version -
>> it could be handled by the <tgmath.h> "abs" generic macro. (That's for
>> C - for C++, you'd prefer a template.)
>>
>> Some of the other functions taking or returning an "intmax_t" would add
>> complications, yes. That's why "intmax_t" would need to be deprecated
>> rather than just dropped.
>>
>>
>
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2021-06-03 10:53 +0200 |
| Message-ID | <s9a5ak$oi0$1@dont-email.me> |
| In reply to | #80122 |
On 03/06/2021 09:08, David Brown wrote:
> On 03/06/2021 00:49, Manfred wrote:
>> On 6/2/2021 11:32 PM, David Brown wrote:
>>> On 02/06/2021 18:43, Manfred wrote:
>>>
>>>> Obviously the div functions give both formally in one operation, taking
>>>> advantage of the ASM instructions that do that.
>>>
>>> A compiler will usually do that two, given "x = a / b; y = a % b;". On
>>> many processors, a single division instruction produces both results and
>>> compilers will take advantage of that.
>>>
>>> When I did a few tests on <https://godbolt.org>, compilers generated
>>> calls to library "div" functions when these were given in the source
>>> code, and direct cpu division instructions for the division and
>>> remainder operators. I must admit it surprised me a little - I'd have
>>> thought the "div" functions would be handled as builtins. But they are
>>> not on the list of gcc "Other builtins" ("abs" is, as are a great many
>>> other standard library functions). I guess the developers simply
>>> haven't bothered - perhaps because the "div" functions are rarely used.
>>
>> Interesting, that's surprising.
>>
>
> Yes. While I don't expect the "div" functions to be much used, it seems
> to me it should a relatively easy optimisation.
>
I reported the lack of "div" builtins in the gcc bugzilla, and it was
marked as a duplicate for an existing one that gave a good explanation
for why "div" is awkward for optimising. The problem is that the layout
of the "div_t" struct is not specified in the standard, and gcc can be
used with different standard libraries that might have "quot" and "rem"
in different orders. Thus an optimisation here would depend on the
source code having included <stdlib.h> (and the compiler knowing the
contents of it), or that the compiler can prove that the layout of the
struct doesn't matter. These would both require significant new
optimisation infrastructure in the compiler. So maybe it will happen
one day, but not yet - probably not until the gcc developers have a more
important use for similar infrastructure.
For MSVC, the same supplier makes both the compiler and the library, and
therefore the compiler knows the structure of div_t and can optimise
appropriately.
[toc] | [prev] | [next] | [standalone]
| From | Manfred <noname@add.invalid> |
|---|---|
| Date | 2021-06-03 16:20 +0200 |
| Message-ID | <s9aof4$l99$1@gioia.aioe.org> |
| In reply to | #80122 |
On 6/3/2021 9:08 AM, David Brown wrote:
> On 03/06/2021 00:49, Manfred wrote:
>> On 6/2/2021 11:32 PM, David Brown wrote:
>>> On 02/06/2021 18:43, Manfred wrote:
>>>> On 6/2/2021 9:29 AM, David Brown wrote:
>>>>> On 01/06/2021 20:21, Manfred wrote:
>>>>>> On 6/1/2021 7:15 PM, David Brown wrote:
>>>> [...]
>> As per their
>> definition, there is no reason for which div should perform worse than
>> '/' and '%'.
>
> The function call overhead here is going to dominate the cost -
> shuffling around data into the right registers, calling the function in
> a library (imagine if it is in a DLL/so), instruction cache misses,
> stacking and restoring other data according to ABI volatile and
> preserved register usage, reduced scope for optimisation with constant
> propagation, inlining, pre-calculating results, etc. There are many
> reasons why it should be worse.
>
Yes, but having "div" as intrinsics is part of picture here.
>> In fact, the only motivation for the *div functions to exist is that
>> they perform better, or at the very least equal, to the pair '/' and '%'.
>> To me it sounds like a matter of QoI.
>>
>
> I am sure that in the early days of C, the div functions would - on some
> systems at least - have performed better than the division operators
> together. But not now - and not for a long time, on most targets.
>
>>>> I know that most optimizing compilers are able to combine a sequence of
>>>> '/' and '%' into a single instruction, but this is relying on
>>>> optimization, and thus not standardized.
>>>
>>> The same could be said about calling "div" - the standard does not give
>>> any indication that it is implemented in any particularly efficient way.
>>> Most likely, it is done by :
>>>
>>> div_t div(int a, int b) {
>>> div_t d;
>>> d.quot = a / b;
>>> d.rem = a % b;
>>> return d;
>>> }
>>>
>>>
>>>> I now we are probably going to disagree on this point, but to me it is
>>>> relevant that some feature, if it is important to the program, be
>>>> possible to express in source code with no need to assume some
>>>> behind-the-scenes compiler behavior.
>>>>
>>>
>>> I don't disagree on that principle at all. But I /do/ disagree about
>>> any assumptions you make about how "div" is implemented, and that it has
>>> any required behaviour or guarantees that you don't get from the
>>> operators.
>>>
>>
>> Well, it's the /definition/ of "div" that it calculates the quotient and
>> the remainder in one go, not an assumption.
>
> The wording is "in a single operation". Since that concept is not
> explicitly defined in the standard (AFAIK), and since there is no way
> that standard can insist that a particular implementation does the
> operation as a single instruction (not all processors have division
> instructions of any sort), that part of the description simply says you
> get both results from one function call.
>
>> In this specific case, the same applies to performance: as I said it is
>> the only reason for it to exist.
>> If the implementation is sloppy then it's good to know, but it's also a
>> different matter.
>
> On most modern processors, no implementation could possibly have a
> library call here that is faster than doing the operations using / and %
> with a single division assembly code. It's not being sloppy - it is
> impossible. You'd have to go out of your way to make an intentially
> poor quality compiler for a call to "div" to be faster than using the
> operators. (Failing to replace the "div" call with inline code is a
> missed optimisation opportunity, and therefore QoI.)
>
Yes, but still the only reason for div to exist is to provide /some/
benefit over '/' and '%', which in the end is only a matter of
efficiency, so an implementation that manages to deliver a 'div' family
of functions that performs worse than the pair of operators still
qualifies as sloppy, at least in my book - this includes missing it as
inline or intrinsics, because, as you say, it makes any chance of
efficiency hopeless.
> I reported the lack of "div" builtins in the gcc bugzilla, and it was
> marked as a duplicate for an existing one that gave a good explanation
> for why "div" is awkward for optimising. The problem is that the layout
> of the "div_t" struct is not specified in the standard, and gcc can be
> used with different standard libraries that might have "quot" and "rem"
> in different orders. Thus an optimisation here would depend on the
> source code having included <stdlib.h> (and the compiler knowing the
> contents of it), or that the compiler can prove that the layout of the
> struct doesn't matter. These would both require significant new
> optimisation infrastructure in the compiler. So maybe it will happen
> one day, but not yet - probably not until the gcc developers have a more
> important use for similar infrastructure.
>
> For MSVC, the same supplier makes both the compiler and the library, and
> therefore the compiler knows the structure of div_t and can optimise
> appropriately.
Your other post (quoted above) reports a reasonable explanation of the
complications involved for gcc - I'd say that from the user's
perspective an implementation consists of the combination compiler +
library, so it simply means that the implementation is suboptimal in
this specific case.
Again, most probably the gcc folks and friends simply didn't bother too
much because this topic is low priority.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2021-06-03 11:20 -0400 |
| Message-ID | <s9arvn$non$1@dont-email.me> |
| In reply to | #80122 |
On 6/3/21 3:08 AM, David Brown wrote: > On 03/06/2021 00:49, Manfred wrote: ... >> As per their >> definition, there is no reason for which div should perform worse than >> '/' and '%'. > > The function call overhead here is going to dominate the cost - > shuffling around data into the right registers, calling the function in > a library (imagine if it is in a DLL/so), instruction cache misses, > stacking and restoring other data according to ABI volatile and > preserved register usage, reduced scope for optimisation with constant > propagation, inlining, pre-calculating results, etc. There are many > reasons why it should be worse. I wouldn't expect function call overhead to be relevant unless div() is used in a context (usually involving function pointers) that prevents div() from being inlined. When it is inlined, I would expect a call to div() to be optimized to essentially the same code as would be generated for separate / and % expressions. Note: reality often fails to live up (or, in some cases, down) to my expectations.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2021-06-03 19:04 +0200 |
| Message-ID | <s9b22h$cr0$1@dont-email.me> |
| In reply to | #80135 |
On 03/06/2021 17:20, James Kuyper wrote: > On 6/3/21 3:08 AM, David Brown wrote: >> On 03/06/2021 00:49, Manfred wrote: > ... >>> As per their >>> definition, there is no reason for which div should perform worse than >>> '/' and '%'. >> >> The function call overhead here is going to dominate the cost - >> shuffling around data into the right registers, calling the function in >> a library (imagine if it is in a DLL/so), instruction cache misses, >> stacking and restoring other data according to ABI volatile and >> preserved register usage, reduced scope for optimisation with constant >> propagation, inlining, pre-calculating results, etc. There are many >> reasons why it should be worse. > > I wouldn't expect function call overhead to be relevant unless div() is > used in a context (usually involving function pointers) that prevents > div() from being inlined. When it is inlined, I would expect a call to > div() to be optimized to essentially the same code as would be generated > for separate / and % expressions. > Note: reality often fails to live up (or, in some cases, down) to my > expectations. > If it were inlined, I would expect it to be optimal in speed and size. But standard library functions are often not inlined unless they are completely replaced by built-ins that have the same semantics. I'm not sure if the standard library functions can be declared as "inline" and defined in headers like <stdlib.h> - it would be interesting to know. But AFAIUI, glibc - for whatever reason - don't like to have inline definitions of in their standard C library headers.
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2021-06-03 22:24 +0000 |
| Message-ID | <aEcuI.59494$zx1.54792@fx20.iad> |
| In reply to | #80136 |
David Brown <david.brown@hesbynett.no> writes:
>On 03/06/2021 17:20, James Kuyper wrote:
>> On 6/3/21 3:08 AM, David Brown wrote:
>>> On 03/06/2021 00:49, Manfred wrote:
>> ...
>>>> As per their
>>>> definition, there is no reason for which div should perform worse than
>>>> '/' and '%'.
>>>
>>> The function call overhead here is going to dominate the cost -
>>> shuffling around data into the right registers, calling the function in
>>> a library (imagine if it is in a DLL/so), instruction cache misses,
>>> stacking and restoring other data according to ABI volatile and
>>> preserved register usage, reduced scope for optimisation with constant
>>> propagation, inlining, pre-calculating results, etc. There are many
>>> reasons why it should be worse.
>>
>> I wouldn't expect function call overhead to be relevant unless div() is
>> used in a context (usually involving function pointers) that prevents
>> div() from being inlined. When it is inlined, I would expect a call to
>> div() to be optimized to essentially the same code as would be generated
>> for separate / and % expressions.
>> Note: reality often fails to live up (or, in some cases, down) to my
>> expectations.
>>
>
>If it were inlined, I would expect it to be optimal in speed and size.
>But standard library functions are often not inlined unless they are
>completely replaced by built-ins that have the same semantics. I'm not
As of GCC 4.8, 'div' wasn't ever inlined, even with -O3.
However, the compiler optimized this into a single idiv:
#include <stdlib.h>
int main(int argc, const char **argv)
{
//div_t qr = div(1234235235, 10);
long q, r;
long a, b;
a = strtol(argv[1], NULL, 0);
b = strtol(argv[2], NULL, 0);
q = a/b;
r = a%b;
return q*8 + r;
}
0000000000400440 <main>:
400440: 55 push %rbp
400441: 31 d2 xor %edx,%edx
400443: 48 89 f5 mov %rsi,%rbp
400446: 53 push %rbx
400447: 48 83 ec 08 sub $0x8,%rsp
40044b: 48 8b 7e 08 mov 0x8(%rsi),%rdi
40044f: 31 f6 xor %esi,%esi
400451: e8 da ff ff ff callq 400430 <strtoul@plt>
400456: 48 8b 7d 10 mov 0x10(%rbp),%rdi
40045a: 48 89 c3 mov %rax,%rbx
40045d: 31 d2 xor %edx,%edx
40045f: 31 f6 xor %esi,%esi
400461: e8 ca ff ff ff callq 400430 <strtoul@plt>
400466: 48 89 c1 mov %rax,%rcx
400469: 48 89 d8 mov %rbx,%rax
40046c: 48 83 c4 08 add $0x8,%rsp
400470: 48 99 cqto
400472: 48 f7 f9 idiv %rcx
400475: 5b pop %rbx
400476: 5d pop %rbp
400477: 8d 04 c2 lea (%rdx,%rax,8),%eax
40047a: c3 retq
40047b: 90 nop
[toc] | [prev] | [next] | [standalone]
| From | Öö Tiib <ootiib@hot.ee> |
|---|---|
| Date | 2021-06-03 16:27 -0700 |
| Message-ID | <3ec77fe7-2c57-4ede-baf3-12b42f52b1afn@googlegroups.com> |
| In reply to | #80141 |
On Friday, 4 June 2021 at 01:24:23 UTC+3, Scott Lurndal wrote: > David Brown <david...@hesbynett.no> writes: > >On 03/06/2021 17:20, James Kuyper wrote: > >> On 6/3/21 3:08 AM, David Brown wrote: > >>> On 03/06/2021 00:49, Manfred wrote: > >> ... > >>>> As per their > >>>> definition, there is no reason for which div should perform worse than > >>>> '/' and '%'. > >>> > >>> The function call overhead here is going to dominate the cost - > >>> shuffling around data into the right registers, calling the function in > >>> a library (imagine if it is in a DLL/so), instruction cache misses, > >>> stacking and restoring other data according to ABI volatile and > >>> preserved register usage, reduced scope for optimisation with constant > >>> propagation, inlining, pre-calculating results, etc. There are many > >>> reasons why it should be worse. > >> > >> I wouldn't expect function call overhead to be relevant unless div() is > >> used in a context (usually involving function pointers) that prevents > >> div() from being inlined. When it is inlined, I would expect a call to > >> div() to be optimized to essentially the same code as would be generated > >> for separate / and % expressions. > >> Note: reality often fails to live up (or, in some cases, down) to my > >> expectations. > >> > > > >If it were inlined, I would expect it to be optimal in speed and size. > >But standard library functions are often not inlined unless they are > >completely replaced by built-ins that have the same semantics. I'm not > > As of GCC 4.8, 'div' wasn't ever inlined, even with -O3. > Maybe with -flto it does?
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2021-06-04 00:36 +0000 |
| Message-ID | <RzeuI.10798$hm1.5022@fx11.iad> |
| In reply to | #80142 |
=?UTF-8?B?w5bDtiBUaWli?= <ootiib@hot.ee> writes: >On Friday, 4 June 2021 at 01:24:23 UTC+3, Scott Lurndal wrote: >> David Brown <david...@hesbynett.no> writes: >> >On 03/06/2021 17:20, James Kuyper wrote: >> >> On 6/3/21 3:08 AM, David Brown wrote: >> >>> On 03/06/2021 00:49, Manfred wrote: >> >> ... >> >>>> As per their >> >>>> definition, there is no reason for which div should perform worse than >> >>>> '/' and '%'. >> >>> >> >>> The function call overhead here is going to dominate the cost - >> >>> shuffling around data into the right registers, calling the function in >> >>> a library (imagine if it is in a DLL/so), instruction cache misses, >> >>> stacking and restoring other data according to ABI volatile and >> >>> preserved register usage, reduced scope for optimisation with constant >> >>> propagation, inlining, pre-calculating results, etc. There are many >> >>> reasons why it should be worse. >> >> >> >> I wouldn't expect function call overhead to be relevant unless div() is >> >> used in a context (usually involving function pointers) that prevents >> >> div() from being inlined. When it is inlined, I would expect a call to >> >> div() to be optimized to essentially the same code as would be generated >> >> for separate / and % expressions. >> >> Note: reality often fails to live up (or, in some cases, down) to my >> >> expectations. >> >> >> > >> >If it were inlined, I would expect it to be optimal in speed and size. >> >But standard library functions are often not inlined unless they are >> >completely replaced by built-ins that have the same semantics. I'm not >> >> As of GCC 4.8, 'div' wasn't ever inlined, even with -O3. >> > >Maybe with -flto it does? Perhaps, but gcc generally documents all the functions that will be inlined in their texinfo documentation, and div is not included in the list of math functions that automatically get builtin status at least in GCC 4.8. Since they're up to GCC11 now, they may have added it to the list. However, if the compiler recognizes cases where both the quotient and remainder are used and generates a single divide instruction, there doesn't seem much need for div at all.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2021-06-04 08:46 +0200 |
| Message-ID | <s9ci94$akn$1@dont-email.me> |
| In reply to | #80143 |
On 04/06/2021 02:36, Scott Lurndal wrote: > =?UTF-8?B?w5bDtiBUaWli?= <ootiib@hot.ee> writes: >> On Friday, 4 June 2021 at 01:24:23 UTC+3, Scott Lurndal wrote: >>> David Brown <david...@hesbynett.no> writes: >>>> On 03/06/2021 17:20, James Kuyper wrote: >>>>> On 6/3/21 3:08 AM, David Brown wrote: >>>>>> On 03/06/2021 00:49, Manfred wrote: >>>>> ... >>>>>>> As per their >>>>>>> definition, there is no reason for which div should perform worse than >>>>>>> '/' and '%'. >>>>>> >>>>>> The function call overhead here is going to dominate the cost - >>>>>> shuffling around data into the right registers, calling the function in >>>>>> a library (imagine if it is in a DLL/so), instruction cache misses, >>>>>> stacking and restoring other data according to ABI volatile and >>>>>> preserved register usage, reduced scope for optimisation with constant >>>>>> propagation, inlining, pre-calculating results, etc. There are many >>>>>> reasons why it should be worse. >>>>> >>>>> I wouldn't expect function call overhead to be relevant unless div() is >>>>> used in a context (usually involving function pointers) that prevents >>>>> div() from being inlined. When it is inlined, I would expect a call to >>>>> div() to be optimized to essentially the same code as would be generated >>>>> for separate / and % expressions. >>>>> Note: reality often fails to live up (or, in some cases, down) to my >>>>> expectations. >>>>> >>>> >>>> If it were inlined, I would expect it to be optimal in speed and size. >>>> But standard library functions are often not inlined unless they are >>>> completely replaced by built-ins that have the same semantics. I'm not >>> >>> As of GCC 4.8, 'div' wasn't ever inlined, even with -O3. >>> >> >> Maybe with -flto it does? > > Perhaps, but gcc generally documents all the functions that will > be inlined in their texinfo documentation, and div is not included > in the list of math functions that automatically get builtin status > at least in GCC 4.8. Since they're up to GCC11 now, they may have > added it to the list. > It has not (because of the weakly specified "div_t" struct that is determined by the library implementation and not the standards or the compiler). <https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html> > However, if the compiler recognizes cases where both the quotient > and remainder are used and generates a single divide instruction, > there doesn't seem much need for div at all. > Exactly my point - as far as I can tell, "div" is a hangover from weak or limited compilers from long ago.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2021-06-05 22:02 -0700 |
| Message-ID | <87czszwppd.fsf@nosuchdomain.example.com> |
| In reply to | #80144 |
David Brown <david.brown@hesbynett.no> writes:
> On 04/06/2021 02:36, Scott Lurndal wrote:
[...]
>> Perhaps, but gcc generally documents all the functions that will
>> be inlined in their texinfo documentation, and div is not included
>> in the list of math functions that automatically get builtin status
>> at least in GCC 4.8. Since they're up to GCC11 now, they may have
>> added it to the list.
>
> It has not (because of the weakly specified "div_t" struct that is
> determined by the library implementation and not the standards or the
> compiler).
>
> <https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html>
This could be done if a future C standard specified the representation
of type div_t (as it does for complex types).
>> However, if the compiler recognizes cases where both the quotient
>> and remainder are used and generates a single divide instruction,
>> there doesn't seem much need for div at all.
>
> Exactly my point - as far as I can tell, "div" is a hangover from weak
> or limited compilers from long ago.
But existing code that uses "div" could still run faster if compilers
were able to inline it.
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips Healthcare
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2021-06-06 11:17 +0200 |
| Message-ID | <s9i3qe$k4f$1@dont-email.me> |
| In reply to | #80177 |
On 06/06/2021 07:02, Keith Thompson wrote: > David Brown <david.brown@hesbynett.no> writes: >> On 04/06/2021 02:36, Scott Lurndal wrote: > [...] >>> Perhaps, but gcc generally documents all the functions that will >>> be inlined in their texinfo documentation, and div is not included >>> in the list of math functions that automatically get builtin status >>> at least in GCC 4.8. Since they're up to GCC11 now, they may have >>> added it to the list. >> >> It has not (because of the weakly specified "div_t" struct that is >> determined by the library implementation and not the standards or the >> compiler). >> >> <https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html> > > This could be done if a future C standard specified the representation > of type div_t (as it does for complex types). One of the suggested ways for handling this situation for gcc is, in fact, to use a complex type as a container for the div_t results. It would use the gcc extension of complex integer types (Gaussian integers, I suppose), precisely because it is a suitable pair of numbers whose structure is known to the compiler. This is just one of these odd things in compilers that seems simple from the outside, but has subtle complications in practice. > >>> However, if the compiler recognizes cases where both the quotient >>> and remainder are used and generates a single divide instruction, >>> there doesn't seem much need for div at all. >> >> Exactly my point - as far as I can tell, "div" is a hangover from weak >> or limited compilers from long ago. > > But existing code that uses "div" could still run faster if compilers > were able to inline it. > Indeed.
[toc] | [prev] | [next] | [standalone]
| From | Manfred <noname@add.invalid> |
|---|---|
| Date | 2021-06-06 18:39 +0200 |
| Message-ID | <s9itn5$1t1r$1@gioia.aioe.org> |
| In reply to | #80180 |
On 6/6/2021 11:17 AM, David Brown wrote: > On 06/06/2021 07:02, Keith Thompson wrote: >> David Brown <david.brown@hesbynett.no> writes: >>> On 04/06/2021 02:36, Scott Lurndal wrote: >> [...] >>>> Perhaps, but gcc generally documents all the functions that will >>>> be inlined in their texinfo documentation, and div is not included >>>> in the list of math functions that automatically get builtin status >>>> at least in GCC 4.8. Since they're up to GCC11 now, they may have >>>> added it to the list. >>> >>> It has not (because of the weakly specified "div_t" struct that is >>> determined by the library implementation and not the standards or the >>> compiler). >>> >>> <https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html> >> >> This could be done if a future C standard specified the representation >> of type div_t (as it does for complex types). > > One of the suggested ways for handling this situation for gcc is, in > fact, to use a complex type as a container for the div_t results. It > would use the gcc extension of complex integer types (Gaussian integers, > I suppose), precisely because it is a suitable pair of numbers whose > structure is known to the compiler. This is just one of these odd > things in compilers that seems simple from the outside, but has subtle > complications in practice. > This suggestion might be justified by the current status of gcc code, however obviously div_t results don't seem ti have much in common with complex numbers. As Keith said, having the layout of div_t standardized could be an option, modulo the politics required to get consensus in the committee - in which btw the cc folks are fairly well represented, I believe. However, I don't think this is strictly required - in fact the compiler already /knows/ the layout of div_t from the headers it parses, so it should be possible to place the appropriate offsets in the generated code. This might not be straightforward though, or anyway enough of a burden to handle compared to the demand for it - admittedly low. >> >>>> However, if the compiler recognizes cases where both the quotient >>>> and remainder are used and generates a single divide instruction, >>>> there doesn't seem much need for div at all. >>> >>> Exactly my point - as far as I can tell, "div" is a hangover from weak >>> or limited compilers from long ago. >> >> But existing code that uses "div" could still run faster if compilers >> were able to inline it. >> > > Indeed. > And not really a hangover from past limitations. I'd say more of a follow up on the tradition of C to have popular ASM features bubble up as language features (think e.g. shift operators).
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2021-06-06 16:33 -0700 |
| Message-ID | <87im2qvaa7.fsf@nosuchdomain.example.com> |
| In reply to | #80180 |
David Brown <david.brown@hesbynett.no> writes:
> On 06/06/2021 07:02, Keith Thompson wrote:
>> David Brown <david.brown@hesbynett.no> writes:
>>> On 04/06/2021 02:36, Scott Lurndal wrote:
>> [...]
>>>> Perhaps, but gcc generally documents all the functions that will
>>>> be inlined in their texinfo documentation, and div is not included
>>>> in the list of math functions that automatically get builtin status
>>>> at least in GCC 4.8. Since they're up to GCC11 now, they may have
>>>> added it to the list.
>>>
>>> It has not (because of the weakly specified "div_t" struct that is
>>> determined by the library implementation and not the standards or the
>>> compiler).
>>>
>>> <https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html>
>>
>> This could be done if a future C standard specified the representation
>> of type div_t (as it does for complex types).
>
> One of the suggested ways for handling this situation for gcc is, in
> fact, to use a complex type as a container for the div_t results. It
> would use the gcc extension of complex integer types (Gaussian integers,
> I suppose), precisely because it is a suitable pair of numbers whose
> structure is known to the compiler. This is just one of these odd
> things in compilers that seems simple from the outside, but has subtle
> complications in practice.
Sure, but the type div_t is still defined in the <stdlib.h> or <cstdlib>
header, and gcc has to work with arbitrary library implementations.
The C standard's requirements for the representation of complex types:
Each complex type has the same representation and alignment
requirements as an array type containing exactly two elements of the
corresponding real type; the first element is equal to the real
part, and the second element to the imaginary part, of the complex
number.
could easily be reworked to specify the representation of div_t
(and ldiv_t, and lldvi_t, and intmaxdiv_t). I strongly suspect
that all existing implementations already define the *div_t types
consistently, with quot at offset 0 and rem following it. If the
layout were specified, gcc could optimize calls to the *div()
functions (assuming it knows that the library that will be used
is conforming).
[...]
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips Healthcare
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
Page 4 of 6 — ← Prev page 1 2 3 [4] 5 6 Next page →
Back to top | Article view | comp.lang.c++
csiph-web