|
|
DescriptionClean up SkFloatBits
- remove dead code
- rewrite float -> int converters
The strategy for the new converters is:
- convert input to double
- floor/ceil/round in double space
- pin that double to [SK_MinS32, SK_MaxS32]
- truncate that double to int32_t
This simpler strategy does not work:
- floor/ceil/round in float space
- pin that float to [SK_MinS32, SK_MaxS32]
- truncate that float to int32_t
SK_MinS32 and SK_MaxS32 are not representable as floats:
they round to the nearest float, ±2^31, which makes the
pin insufficient for floats near SK_MinS32 (-2^31+1) or
SK_MaxS32 (+2^31-1).
float only has 24 bits of precision, and we need 31.
double can represent all integers up to 50-something bits.
An alternative is to pin in float to ±2147483520, the last
exactly representable float before SK_MaxS32 (127 too small).
Our tests test that we round as floor(x+0.5), which can
return different numbers than round(x) for negative x.
So this CL explicitly uses floor(x+0.5).
I've updated the tests with ±inf and ±NaN, and tried to
make them a little clearer, especially using SK_MinS32
instead of -SK_MaxS32.
I have not timed anything here. I have never seen any of these
methods in a profile.
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2012333003
Committed: https://skia.googlesource.com/skia/+/785a5b941a4d74a1f272729fe8dca55c6eda6bb8
Patch Set 1 #Patch Set 2 : clearer #Patch Set 3 : explicit cast #Patch Set 4 : add a bench #Patch Set 5 : member #
Messages
Total messages: 34 (19 generated)
Description was changed from ========== Clean up SkFloatBits - remove dead code - rewrite float -> int converters The strategy for the new converters is: - convert input to double - floor/ceil/round in double space - clamp that double to [SK_MinS32, SK_MaxS32] - truncate that double to int32_t This simpler strategy does not work: - floor/ceil/round in float space - clamp that float to [SK_MinS32, SK_MaxS32] - truncate that float to int32_t SK_MinS32 and SK_MaxS32 are not representable as floats: they round to the nearest float, ±2^31, which makes the pin insufficient for floats near SK_MinS32 (-2^31+1) or SK_MaxS32 (+2^31-1). float only has 24 bits of precision, and we need 31. Our tests test that we round as floor(x+0.5), which can return different numbers than round(x) for positive x. So this CL explicitly uses floor(x+0.5). BUG=skia: ========== to ========== Clean up SkFloatBits - remove dead code - rewrite float -> int converters The strategy for the new converters is: - convert input to double - floor/ceil/round in double space - clamp that double to [SK_MinS32, SK_MaxS32] - truncate that double to int32_t This simpler strategy does not work: - floor/ceil/round in float space - clamp that float to [SK_MinS32, SK_MaxS32] - truncate that float to int32_t SK_MinS32 and SK_MaxS32 are not representable as floats: they round to the nearest float, ±2^31, which makes the pin insufficient for floats near SK_MinS32 (-2^31+1) or SK_MaxS32 (+2^31-1). float only has 24 bits of precision, and we need 31. Our tests test that we round as floor(x+0.5), which can return different numbers than round(x) for positive x. So this CL explicitly uses floor(x+0.5). BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2012333003 ==========
Description was changed from ========== Clean up SkFloatBits - remove dead code - rewrite float -> int converters The strategy for the new converters is: - convert input to double - floor/ceil/round in double space - clamp that double to [SK_MinS32, SK_MaxS32] - truncate that double to int32_t This simpler strategy does not work: - floor/ceil/round in float space - clamp that float to [SK_MinS32, SK_MaxS32] - truncate that float to int32_t SK_MinS32 and SK_MaxS32 are not representable as floats: they round to the nearest float, ±2^31, which makes the pin insufficient for floats near SK_MinS32 (-2^31+1) or SK_MaxS32 (+2^31-1). float only has 24 bits of precision, and we need 31. Our tests test that we round as floor(x+0.5), which can return different numbers than round(x) for positive x. So this CL explicitly uses floor(x+0.5). BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2012333003 ========== to ========== Clean up SkFloatBits - remove dead code - rewrite float -> int converters The strategy for the new converters is: - convert input to double - floor/ceil/round in double space - clamp that double to [SK_MinS32, SK_MaxS32] - truncate that double to int32_t This simpler strategy does not work: - floor/ceil/round in float space - clamp that float to [SK_MinS32, SK_MaxS32] - truncate that float to int32_t SK_MinS32 and SK_MaxS32 are not representable as floats: they round to the nearest float, ±2^31, which makes the pin insufficient for floats near SK_MinS32 (-2^31+1) or SK_MaxS32 (+2^31-1). float only has 24 bits of precision, and we need 31. Our tests test that we round as floor(x+0.5), which can return different numbers than round(x) for positive x. So this CL explicitly uses floor(x+0.5). I've updated the tests with ±inf and ±NaN, and tried to make them a little clearer, especially using SK_MinS32 instead of -SK_MaxS32. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2012333003 ==========
Description was changed from ========== Clean up SkFloatBits - remove dead code - rewrite float -> int converters The strategy for the new converters is: - convert input to double - floor/ceil/round in double space - clamp that double to [SK_MinS32, SK_MaxS32] - truncate that double to int32_t This simpler strategy does not work: - floor/ceil/round in float space - clamp that float to [SK_MinS32, SK_MaxS32] - truncate that float to int32_t SK_MinS32 and SK_MaxS32 are not representable as floats: they round to the nearest float, ±2^31, which makes the pin insufficient for floats near SK_MinS32 (-2^31+1) or SK_MaxS32 (+2^31-1). float only has 24 bits of precision, and we need 31. Our tests test that we round as floor(x+0.5), which can return different numbers than round(x) for positive x. So this CL explicitly uses floor(x+0.5). I've updated the tests with ±inf and ±NaN, and tried to make them a little clearer, especially using SK_MinS32 instead of -SK_MaxS32. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2012333003 ========== to ========== Clean up SkFloatBits - remove dead code - rewrite float -> int converters The strategy for the new converters is: - convert input to double - floor/ceil/round in double space - clamp that double to [SK_MinS32, SK_MaxS32] - truncate that double to int32_t This simpler strategy does not work: - floor/ceil/round in float space - clamp that float to [SK_MinS32, SK_MaxS32] - truncate that float to int32_t SK_MinS32 and SK_MaxS32 are not representable as floats: they round to the nearest float, ±2^31, which makes the pin insufficient for floats near SK_MinS32 (-2^31+1) or SK_MaxS32 (+2^31-1). float only has 24 bits of precision, and we need 31. double can represent all integers up to 50-something bits. Our tests test that we round as floor(x+0.5), which can return different numbers than round(x) for positive x. So this CL explicitly uses floor(x+0.5). I've updated the tests with ±inf and ±NaN, and tried to make them a little clearer, especially using SK_MinS32 instead of -SK_MaxS32. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2012333003 ==========
Description was changed from ========== Clean up SkFloatBits - remove dead code - rewrite float -> int converters The strategy for the new converters is: - convert input to double - floor/ceil/round in double space - clamp that double to [SK_MinS32, SK_MaxS32] - truncate that double to int32_t This simpler strategy does not work: - floor/ceil/round in float space - clamp that float to [SK_MinS32, SK_MaxS32] - truncate that float to int32_t SK_MinS32 and SK_MaxS32 are not representable as floats: they round to the nearest float, ±2^31, which makes the pin insufficient for floats near SK_MinS32 (-2^31+1) or SK_MaxS32 (+2^31-1). float only has 24 bits of precision, and we need 31. double can represent all integers up to 50-something bits. Our tests test that we round as floor(x+0.5), which can return different numbers than round(x) for positive x. So this CL explicitly uses floor(x+0.5). I've updated the tests with ±inf and ±NaN, and tried to make them a little clearer, especially using SK_MinS32 instead of -SK_MaxS32. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2012333003 ========== to ========== Clean up SkFloatBits - remove dead code - rewrite float -> int converters The strategy for the new converters is: - convert input to double - floor/ceil/round in double space - clamp that double to [SK_MinS32, SK_MaxS32] - truncate that double to int32_t This simpler strategy does not work: - floor/ceil/round in float space - clamp that float to [SK_MinS32, SK_MaxS32] - truncate that float to int32_t SK_MinS32 and SK_MaxS32 are not representable as floats: they round to the nearest float, ±2^31, which makes the pin insufficient for floats near SK_MinS32 (-2^31+1) or SK_MaxS32 (+2^31-1). float only has 24 bits of precision, and we need 31. double can represent all integers up to 50-something bits. Our tests test that we round as floor(x+0.5), which can return different numbers than round(x) for positive x. So this CL explicitly uses floor(x+0.5). I've updated the tests with ±inf and ±NaN, and tried to make them a little clearer, especially using SK_MinS32 instead of -SK_MaxS32. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2012333003 ==========
Description was changed from ========== Clean up SkFloatBits - remove dead code - rewrite float -> int converters The strategy for the new converters is: - convert input to double - floor/ceil/round in double space - clamp that double to [SK_MinS32, SK_MaxS32] - truncate that double to int32_t This simpler strategy does not work: - floor/ceil/round in float space - clamp that float to [SK_MinS32, SK_MaxS32] - truncate that float to int32_t SK_MinS32 and SK_MaxS32 are not representable as floats: they round to the nearest float, ±2^31, which makes the pin insufficient for floats near SK_MinS32 (-2^31+1) or SK_MaxS32 (+2^31-1). float only has 24 bits of precision, and we need 31. double can represent all integers up to 50-something bits. Our tests test that we round as floor(x+0.5), which can return different numbers than round(x) for positive x. So this CL explicitly uses floor(x+0.5). I've updated the tests with ±inf and ±NaN, and tried to make them a little clearer, especially using SK_MinS32 instead of -SK_MaxS32. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2012333003 ========== to ========== Clean up SkFloatBits - remove dead code - rewrite float -> int converters The strategy for the new converters is: - convert input to double - floor/ceil/round in double space - clamp that double to [SK_MinS32, SK_MaxS32] - truncate that double to int32_t This simpler strategy does not work: - floor/ceil/round in float space - clamp that float to [SK_MinS32, SK_MaxS32] - truncate that float to int32_t SK_MinS32 and SK_MaxS32 are not representable as floats: they round to the nearest float, ±2^31, which makes the pin insufficient for floats near SK_MinS32 (-2^31+1) or SK_MaxS32 (+2^31-1). float only has 24 bits of precision, and we need 31. double can represent all integers up to 50-something bits. An alternative is to clamp to ±2147483520, the last exactly representable float before SK_MaxS32 (127 too small). Our tests test that we round as floor(x+0.5), which can return different numbers than round(x) for positive x. So this CL explicitly uses floor(x+0.5). I've updated the tests with ±inf and ±NaN, and tried to make them a little clearer, especially using SK_MinS32 instead of -SK_MaxS32. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2012333003 ==========
Description was changed from ========== Clean up SkFloatBits - remove dead code - rewrite float -> int converters The strategy for the new converters is: - convert input to double - floor/ceil/round in double space - clamp that double to [SK_MinS32, SK_MaxS32] - truncate that double to int32_t This simpler strategy does not work: - floor/ceil/round in float space - clamp that float to [SK_MinS32, SK_MaxS32] - truncate that float to int32_t SK_MinS32 and SK_MaxS32 are not representable as floats: they round to the nearest float, ±2^31, which makes the pin insufficient for floats near SK_MinS32 (-2^31+1) or SK_MaxS32 (+2^31-1). float only has 24 bits of precision, and we need 31. double can represent all integers up to 50-something bits. An alternative is to clamp to ±2147483520, the last exactly representable float before SK_MaxS32 (127 too small). Our tests test that we round as floor(x+0.5), which can return different numbers than round(x) for positive x. So this CL explicitly uses floor(x+0.5). I've updated the tests with ±inf and ±NaN, and tried to make them a little clearer, especially using SK_MinS32 instead of -SK_MaxS32. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2012333003 ========== to ========== Clean up SkFloatBits - remove dead code - rewrite float -> int converters The strategy for the new converters is: - convert input to double - floor/ceil/round in double space - clamp that double to [SK_MinS32, SK_MaxS32] - truncate that double to int32_t This simpler strategy does not work: - floor/ceil/round in float space - clamp that float to [SK_MinS32, SK_MaxS32] - truncate that float to int32_t SK_MinS32 and SK_MaxS32 are not representable as floats: they round to the nearest float, ±2^31, which makes the pin insufficient for floats near SK_MinS32 (-2^31+1) or SK_MaxS32 (+2^31-1). float only has 24 bits of precision, and we need 31. double can represent all integers up to 50-something bits. An alternative is to clamp in float to ±2147483520, the last exactly representable float before SK_MaxS32 (127 too small). Our tests test that we round as floor(x+0.5), which can return different numbers than round(x) for positive x. So this CL explicitly uses floor(x+0.5). I've updated the tests with ±inf and ±NaN, and tried to make them a little clearer, especially using SK_MinS32 instead of -SK_MaxS32. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2012333003 ==========
Description was changed from ========== Clean up SkFloatBits - remove dead code - rewrite float -> int converters The strategy for the new converters is: - convert input to double - floor/ceil/round in double space - clamp that double to [SK_MinS32, SK_MaxS32] - truncate that double to int32_t This simpler strategy does not work: - floor/ceil/round in float space - clamp that float to [SK_MinS32, SK_MaxS32] - truncate that float to int32_t SK_MinS32 and SK_MaxS32 are not representable as floats: they round to the nearest float, ±2^31, which makes the pin insufficient for floats near SK_MinS32 (-2^31+1) or SK_MaxS32 (+2^31-1). float only has 24 bits of precision, and we need 31. double can represent all integers up to 50-something bits. An alternative is to clamp in float to ±2147483520, the last exactly representable float before SK_MaxS32 (127 too small). Our tests test that we round as floor(x+0.5), which can return different numbers than round(x) for positive x. So this CL explicitly uses floor(x+0.5). I've updated the tests with ±inf and ±NaN, and tried to make them a little clearer, especially using SK_MinS32 instead of -SK_MaxS32. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2012333003 ========== to ========== Clean up SkFloatBits - remove dead code - rewrite float -> int converters The strategy for the new converters is: - convert input to double - floor/ceil/round in double space - pin that double to [SK_MinS32, SK_MaxS32] - truncate that double to int32_t This simpler strategy does not work: - floor/ceil/round in float space - pin that float to [SK_MinS32, SK_MaxS32] - truncate that float to int32_t SK_MinS32 and SK_MaxS32 are not representable as floats: they round to the nearest float, ±2^31, which makes the pin insufficient for floats near SK_MinS32 (-2^31+1) or SK_MaxS32 (+2^31-1). float only has 24 bits of precision, and we need 31. double can represent all integers up to 50-something bits. An alternative is to pin in float to ±2147483520, the last exactly representable float before SK_MaxS32 (127 too small). Our tests test that we round as floor(x+0.5), which can return different numbers than round(x) for positive x. So this CL explicitly uses floor(x+0.5). I've updated the tests with ±inf and ±NaN, and tried to make them a little clearer, especially using SK_MinS32 instead of -SK_MaxS32. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2012333003 ==========
The CQ bit was checked by mtklein@google.com to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/patch-status/2012333003/1 View timeline at https://chromium-cq-status.appspot.com/patch-timeline/2012333003/1
Description was changed from ========== Clean up SkFloatBits - remove dead code - rewrite float -> int converters The strategy for the new converters is: - convert input to double - floor/ceil/round in double space - pin that double to [SK_MinS32, SK_MaxS32] - truncate that double to int32_t This simpler strategy does not work: - floor/ceil/round in float space - pin that float to [SK_MinS32, SK_MaxS32] - truncate that float to int32_t SK_MinS32 and SK_MaxS32 are not representable as floats: they round to the nearest float, ±2^31, which makes the pin insufficient for floats near SK_MinS32 (-2^31+1) or SK_MaxS32 (+2^31-1). float only has 24 bits of precision, and we need 31. double can represent all integers up to 50-something bits. An alternative is to pin in float to ±2147483520, the last exactly representable float before SK_MaxS32 (127 too small). Our tests test that we round as floor(x+0.5), which can return different numbers than round(x) for positive x. So this CL explicitly uses floor(x+0.5). I've updated the tests with ±inf and ±NaN, and tried to make them a little clearer, especially using SK_MinS32 instead of -SK_MaxS32. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2012333003 ========== to ========== Clean up SkFloatBits - remove dead code - rewrite float -> int converters The strategy for the new converters is: - convert input to double - floor/ceil/round in double space - pin that double to [SK_MinS32, SK_MaxS32] - truncate that double to int32_t This simpler strategy does not work: - floor/ceil/round in float space - pin that float to [SK_MinS32, SK_MaxS32] - truncate that float to int32_t SK_MinS32 and SK_MaxS32 are not representable as floats: they round to the nearest float, ±2^31, which makes the pin insufficient for floats near SK_MinS32 (-2^31+1) or SK_MaxS32 (+2^31-1). float only has 24 bits of precision, and we need 31. double can represent all integers up to 50-something bits. An alternative is to pin in float to ±2147483520, the last exactly representable float before SK_MaxS32 (127 too small). Our tests test that we round as floor(x+0.5), which can return different numbers than round(x) for positive x. So this CL explicitly uses floor(x+0.5). I've updated the tests with ±inf and ±NaN, and tried to make them a little clearer, especially using SK_MinS32 instead of -SK_MaxS32. I have not timed anything here. I have never seen any of these methods in a profile. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2012333003 ==========
Description was changed from ========== Clean up SkFloatBits - remove dead code - rewrite float -> int converters The strategy for the new converters is: - convert input to double - floor/ceil/round in double space - pin that double to [SK_MinS32, SK_MaxS32] - truncate that double to int32_t This simpler strategy does not work: - floor/ceil/round in float space - pin that float to [SK_MinS32, SK_MaxS32] - truncate that float to int32_t SK_MinS32 and SK_MaxS32 are not representable as floats: they round to the nearest float, ±2^31, which makes the pin insufficient for floats near SK_MinS32 (-2^31+1) or SK_MaxS32 (+2^31-1). float only has 24 bits of precision, and we need 31. double can represent all integers up to 50-something bits. An alternative is to pin in float to ±2147483520, the last exactly representable float before SK_MaxS32 (127 too small). Our tests test that we round as floor(x+0.5), which can return different numbers than round(x) for positive x. So this CL explicitly uses floor(x+0.5). I've updated the tests with ±inf and ±NaN, and tried to make them a little clearer, especially using SK_MinS32 instead of -SK_MaxS32. I have not timed anything here. I have never seen any of these methods in a profile. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2012333003 ========== to ========== Clean up SkFloatBits - remove dead code - rewrite float -> int converters The strategy for the new converters is: - convert input to double - floor/ceil/round in double space - pin that double to [SK_MinS32, SK_MaxS32] - truncate that double to int32_t This simpler strategy does not work: - floor/ceil/round in float space - pin that float to [SK_MinS32, SK_MaxS32] - truncate that float to int32_t SK_MinS32 and SK_MaxS32 are not representable as floats: they round to the nearest float, ±2^31, which makes the pin insufficient for floats near SK_MinS32 (-2^31+1) or SK_MaxS32 (+2^31-1). float only has 24 bits of precision, and we need 31. double can represent all integers up to 50-something bits. An alternative is to pin in float to ±2147483520, the last exactly representable float before SK_MaxS32 (127 too small). Our tests test that we round as floor(x+0.5), which can return different numbers than round(x) for negative x. So this CL explicitly uses floor(x+0.5). I've updated the tests with ±inf and ±NaN, and tried to make them a little clearer, especially using SK_MinS32 instead of -SK_MaxS32. I have not timed anything here. I have never seen any of these methods in a profile. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2012333003 ==========
Dry run: None
The CQ bit was checked by mtklein@chromium.org to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/patch-status/2012333003/40001 View timeline at https://chromium-cq-status.appspot.com/patch-timeline/2012333003/40001
mtklein@chromium.org changed reviewers: + fmalita@chromium.org, reed@google.com - mtklein@google.com
You guys got me curious with that other CL.
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: This issue passed the CQ dry run.
Dry run: None
LGTM Real-world impact aside, I would expect the new impl to be cheaper than the old branchy stuff. Is my expectation founded? (calibrating my assumptions)
On 2016/05/27 13:10:16, f(malita) wrote: > LGTM > > Real-world impact aside, I would expect the new impl to be cheaper than the old > branchy stuff. Is my expectation founded? > > (calibrating my assumptions) Yeah, I suspect so. I can speak directly to x86. Most of these steps are one or two instructions there: - convert float -> double: ~1 cycle - floor/ceil in double space: a function call over to a single 3-6 cycle instruction on machines with SSE 4.1 - pin: ~6 cycles - trunc to int32_t: ~5 cycles We don't actually pay much to do this in doubles: that fastest float version clamping to ±2147483520 would only be that ~1 float -> double cycle quicker. All the rest costs the same for floats or doubles.
I think measuring the speed of the following might be interesting: 1. old impl 2. this CL 3. this CL modulo using floats instead of doubles (knowing that the returned int won't be max32 I will try to cons that up today (hopefully)
On 2016/05/27 at 14:29:15, reed wrote: > I think measuring the speed of the following might be interesting: > > 1. old impl > 2. this CL > 3. this CL modulo using floats instead of doubles (knowing that the returned int won't be max32 > > I will try to cons that up today (hopefully) PS4 adds a bench. The old code runs on my machine in 3.67ms, this CL in 2.78ms, and this CL with float clamping to ±2147483520 in 2.78ms.
thanks for benching! lgtm
The CQ bit was checked by mtklein@google.com
The patchset sent to the CQ was uploaded after l-g-t-m from fmalita@chromium.org Link to the patchset: https://codereview.chromium.org/2012333003/#ps60001 (title: "add a bench")
CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/patch-status/2012333003/60001 View timeline at https://chromium-cq-status.appspot.com/patch-timeline/2012333003/60001
The CQ bit was unchecked by commit-bot@chromium.org
Try jobs failed on following builders: Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Debug-Trybot on client.skia (JOB_FAILED, http://build.chromium.org/p/client.skia/builders/Test-Ubuntu-GCC-GCE-CPU-AVX2...)
The CQ bit was checked by mtklein@chromium.org
The patchset sent to the CQ was uploaded after l-g-t-m from fmalita@chromium.org, reed@google.com Link to the patchset: https://codereview.chromium.org/2012333003/#ps80001 (title: "member")
CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/patch-status/2012333003/80001 View timeline at https://chromium-cq-status.appspot.com/patch-timeline/2012333003/80001
Message was sent while issue was closed.
Description was changed from ========== Clean up SkFloatBits - remove dead code - rewrite float -> int converters The strategy for the new converters is: - convert input to double - floor/ceil/round in double space - pin that double to [SK_MinS32, SK_MaxS32] - truncate that double to int32_t This simpler strategy does not work: - floor/ceil/round in float space - pin that float to [SK_MinS32, SK_MaxS32] - truncate that float to int32_t SK_MinS32 and SK_MaxS32 are not representable as floats: they round to the nearest float, ±2^31, which makes the pin insufficient for floats near SK_MinS32 (-2^31+1) or SK_MaxS32 (+2^31-1). float only has 24 bits of precision, and we need 31. double can represent all integers up to 50-something bits. An alternative is to pin in float to ±2147483520, the last exactly representable float before SK_MaxS32 (127 too small). Our tests test that we round as floor(x+0.5), which can return different numbers than round(x) for negative x. So this CL explicitly uses floor(x+0.5). I've updated the tests with ±inf and ±NaN, and tried to make them a little clearer, especially using SK_MinS32 instead of -SK_MaxS32. I have not timed anything here. I have never seen any of these methods in a profile. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2012333003 ========== to ========== Clean up SkFloatBits - remove dead code - rewrite float -> int converters The strategy for the new converters is: - convert input to double - floor/ceil/round in double space - pin that double to [SK_MinS32, SK_MaxS32] - truncate that double to int32_t This simpler strategy does not work: - floor/ceil/round in float space - pin that float to [SK_MinS32, SK_MaxS32] - truncate that float to int32_t SK_MinS32 and SK_MaxS32 are not representable as floats: they round to the nearest float, ±2^31, which makes the pin insufficient for floats near SK_MinS32 (-2^31+1) or SK_MaxS32 (+2^31-1). float only has 24 bits of precision, and we need 31. double can represent all integers up to 50-something bits. An alternative is to pin in float to ±2147483520, the last exactly representable float before SK_MaxS32 (127 too small). Our tests test that we round as floor(x+0.5), which can return different numbers than round(x) for negative x. So this CL explicitly uses floor(x+0.5). I've updated the tests with ±inf and ±NaN, and tried to make them a little clearer, especially using SK_MinS32 instead of -SK_MaxS32. I have not timed anything here. I have never seen any of these methods in a profile. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2012333003 Committed: https://skia.googlesource.com/skia/+/785a5b941a4d74a1f272729fe8dca55c6eda6bb8 ==========
Message was sent while issue was closed.
Committed patchset #5 (id:80001) as https://skia.googlesource.com/skia/+/785a5b941a4d74a1f272729fe8dca55c6eda6bb8 |