【问题标题】:How to convert large number of uint_8 into array of floats in C?如何将大量 uint_8 转换为 C 中的浮点数组?
【发布时间】:2012-09-26 15:24:46
【问题描述】:

我正在读取(以二进制格式)一个无符号 8 位整数文件,然后我需要将其转换为浮点数组。通常我会做如下的事情:

uint8_t *s1_tmp = (uint8_t *)malloc(sizeof(uint8_t)*num_elements);
float *s1 = (float *)malloc(sizeof(float)*num_elements);

fread(s1_tmp, sizeof(uint8_t), num_elements, file_id);

for(int i = 0; i < num_elements; i++){
    s1[i] = s1_tmp[i];
}

free(s1_tmp)

可以肯定的是,没有灵感,但它确实有效。然而,目前num_elements 大约是 270 万,所以这个过程超级慢而且 IMO 浪费。

有没有更好的方法将 8 位整数读入浮点数或将 uint8_t 数组转换为浮点数数组?

【问题讨论】:

  • 您是否考虑过使用 SIMD 来做这件事?
  • 我假设您正试图通过存储 uint8_t 而不是 float 来节省一些空间。逐一转换是最好的。
  • 不要转换malloc 的返回值,如果可能的话最好完全避免转换。 stackoverflow.com/questions/605845/…
  • 我正在运行 Visual C++,所以强制转换是必要的。

标签: c arrays file-io type-conversion


【解决方案1】:

首先,这将受 I/O 限制,因为读取数据。其次,它将受内存限制。如果将转换与读取交错,您将获得更好的缓存性能。

选择一些合理的缓冲区大小,该大小足够大以获得良好的 I/O 性能,但又足够小以适合您的缓存,可能是 8-32 KB 左右。读入这么多数据,转换并重复。

例如:

#define BUFSIZE 16384
uint8_t *buffer = malloc(BUFSIZE);
float *s1 = malloc(num_elements * sizeof(float));

int total_read = 0;
int n;
while(total_read < num_elements && (n = fread(buffer, 1, BUFSIZE, file_id)) > 0)
{
    n = min(n, num_elements - total_read);
    for(int i = 0; i < n; i++)
        s1[total_read + i] = (float)buffer[i];
    total_read += n;
}
free(buffer);

您还可以通过使用 SIMD 操作一次转换多个项目来提高性能。但是,fread 的 I/O 仍然会成为总体性能的瓶颈,因此您可能会从 SIMD 中看到多少改进是值得怀疑的。

由于您要转换大量的uint8_t 值,因此您完全有可能通过使用查找表而不是进行整数到浮点的转换来获得一些改进的性能。您只需要一个包含 256 个浮点值 (1 KB) 的查找表,它很容易放入缓存中。我不知道这是否会更快,因此您绝对应该分析代码以找出最佳选择。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-27
    • 1970-01-01
    • 2018-12-08
    • 1970-01-01
    • 2019-04-01
    • 2011-06-23
    相关资源
    最近更新 更多