gpt4 book ai didi

floating-point - 将 24 位整数快速、便携地转换为 float ,不会丢失任何位

转载 作者:行者123 更新时间:2023-12-04 06:47:37 26 4
gpt4 key购买 nike

[0, 1) 中生成随机统一 float 时,TensorFlow 目前使用 bit twiddling[1, 2) 中的 23 位整数转换为 float ,然后减一:

// Helper function to convert an 32-bit integer to a float between [0..1).
PHILOX_DEVICE_INLINE float Uint32ToFloat(uint32 x) {
// IEEE754 floats are formatted as follows (MSB first):
// sign(1) exponent(8) mantissa(23)
// Conceptually construct the following:
// sign == 0
// exponent == 127 -- an excess 127 representation of a zero exponent
// mantissa == 23 random bits
const uint32 man = x & 0x7fffffu; // 23 bit mantissa
const uint32 exp = static_cast<uint32>(127);
const uint32 val = (exp << 23) | man;

// Assumes that endian-ness is same for float and uint32.
float result;
memcpy(&result, &val, sizeof(val));
return result - 1.0f;
}

这让我很恼火,因为减一意味着我们只能得到 23 位精度,而不是可用的 24 位精度。不幸的是,朴素算法在 CPU 上慢了大约 9%(在 GPU 上速度相同):

// Helper function to convert an 32-bit integer to a float between [0..1).
PHILOX_DEVICE_INLINE float Uint32ToFloat(uint32 x) {
return 0x1p-32f * static_cast<float>(x);
}

我还尝试过显式截断为 24 位,以防它告诉编译器舍入模式标志无关紧要;这并没有解决问题:

PHILOX_DEVICE_INLINE float Uint32ToFloat(uint32 x) {
return 0x1p-24f * static_cast<float>(x & ((1 << 24) - 1));
}

有没有办法在不牺牲性能的情况下获得完整的 24 位可用精度?我很确定我可以在汇编中做到这一点,但需要可移植性。

请注意,对于小 float 有时,剩下的 8 位精度并不有趣:我只关心丢失的一位。

最佳答案

你可以尝试在第24位置位时不做减法:


const uint32 exp = static_cast<uint32>(126); // 0.5

if ((x & 0x800000) == 0) result -= 0.5f;
return result;
}

不过第24位9%的penalty已经很不错了,不一定会更快。 (在这里你有时会避免减法的代价,但总是付出测试和条件分支的代价。我会让你做时间安排:0x800000 掩码可以与其余部分并行完成,但条件分支的成本完全取决于实践中值的分布。)

对于 GPU,这可以很容易地实现无分支,方法是始终执行减法,然后执行条件移动,但编译器应该自动执行此操作。

关于floating-point - 将 24 位整数快速、便携地转换为 float ,不会丢失任何位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35350699/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com