Julia: `widen` should not widen to more than 32 bits unless necessary

Created on 14 Dec 2015  Â·  16Comments  Â·  Source: JuliaLang/julia

As discussed in #14362: 32-bit integer division is significantly faster than 64-bit integer division.

Most helpful comment

This will also impact 16-bit values - they will widen to 32 bits regardless of the native width (right now both 8 and 16 bits widen to Int / UInt). Is that OK?

All 16 comments

Some other arguments in favour:

  1. consistency across platforms (widen(Int(8)) will do the same thing on 32 & 64 bit)
  2. smaller integers can have bigger gains from vectorization

Does it make sense to also only widen 8 bit integers to 16 bits?

It does, but I'm afraid this might break cases where people use reduction operations on arrays of 8-bit types. I'd argue that those cases should use explicit type conversions, but since there doesn't seem to be a performance benefit of 16-bit over 32-bit I'd stay on the safe side for the moment.

OTOH it would be nice to have a simple rule like "widen returns a type with twice the number of bytes". Without the reasoning you give, it won't be immediately obvious to everybody why Int8 would be an exception.

The documentation of widen seems intentionally vague, and only promises a type that is "larger" in some sense, and which can hold all the values of the given type. This leaves much room for efficiency.

On the other hand, many algorithms expect at type that is at least "twice as large" (e.g. for a widening multiplication). Maybe this requirement should be updated. And maybe we should distinguish between "widen to the smallest type larger than the current type", "widen to the smallest type at least twice as large than the current type", and "widen to the next-larger efficient type"... but this would most likely be overkill.

Yeah, giving a strict definition that would be valid for all cases may not be practical. But following a simple rule for common integer types can still help making the result predictable.

widen would be pretty useless if it doesn't at least hold all products.

I think the only case it doesn't hold is BigFloat (well, and Float64 if the user has changed their set_bigfloat_precision).

I'm very late to the party but I was surprised that widen(UInt8) did not result in UInt16. Is it possible to revisit this?

Yes, possibly --- I'm curious what your application is though.

Note that the behaviour change here was switched in #26859

I would be in favour of a "widen gives twice the bytes", but keeping sum/prod behaviour the same.

Yes, possibly --- I'm curious what your application is though.

For me, space saving takes precedence over "this width is natively faster than this other width", so I'd prefer a widen that would result in the next-largest valid primitive type as opposed to one that's "twice as wide in most cases, but sometimes 4x as wide since that's faster on some machines".

@simonbyrne - sorry - I missed the followup. Let me review that. (Edit - yep, thanks. I did miss this, but it doesn't change my request, I don't think.)

I'm fine with widen giving twice the bits. Seems reasonable.

Thanks. I'll make a PR.

This will also impact 16-bit values - they will widen to 32 bits regardless of the native width (right now both 8 and 16 bits widen to Int / UInt). Is that OK?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

StefanKarpinski picture StefanKarpinski  Â·  3Comments

omus picture omus  Â·  3Comments

Keno picture Keno  Â·  3Comments

helgee picture helgee  Â·  3Comments

i-apellaniz picture i-apellaniz  Â·  3Comments