如何将巨大的头部分配数组设置为特定的浮点数 C++

How to set a huge head allocate array as specific float number C++

起初,我使用Intel Math Kernel Library分配了一个巨大的块内存API。之后我想将此数组设置为特定值,例如 1234.5678。我打算用void* memset( void* dest, int ch, std::size_t count );这个函数,但是好像这个函数只能设置int值。我可以使用简单的 for 循环来解决这个问题。但是,我认为使用 for loop 为这么大的块设置初始值并不是很有效。所以我的问题是

  1. 我有没有另一种方法可以在不使用 for loop
  2. 的情况下初始化这么大的块内存

您可以使用 std::fill_n 为数组的每个值分配一个值

#include <algorithm>

std::fill_n(data, count, 1234.5678);

请注意,即使您使用原始 for 循环,许多编译器也会生成相同的代码

for (std::size_t i = 0; i < count; ++i)
{
    data[i] = 1234.5678;
}

查看此 Compiler Explorer 示例,在上述两种情况下生成相同的汇编代码

void fill_a(double *,unsigned __int64) PROC                         ; fill_a
$LN14:
        sub     rsp, 8
        test    rdx, rdx
        je      SHORT $LN6@fill_a
        mov     QWORD PTR [rsp], rdi
        mov     rax, 4653144502051863213      ; 40934a456d5cfaadH
        mov     rdi, rcx
        mov     rcx, rdx
        rep stosq
        mov     rdi, QWORD PTR [rsp]
$LN6@fill_a:
        add     rsp, 8
        ret     0

I plan to use the void* memset( void* dest, int ch, std::size_t count ); function, but it seems that this function can only set int value.

您实际上可以使用 memset 来设置 floats1 的值,或者实际上是任何简单的可复制类型。 int ch 只是将复制到数据上的字节的值。

但这确实意味着您不能使用 memset 为多字节类型设置任意值,因为所有字节都会重复。例如,您可以将整数设置为 0,即四个 0 字节,或将四字节整数设置为 4369,即四个 1 字节。

如果是符合 IEEE 754 标准的 32 位浮点数,您可以将 memset 设置为值 785.066650391F,例如:std::memset(ptr, count * sizeof(float), 0x44)。这是因为该特定数字由四个重复的 0x44 字节组成。

specific value, for example 1234.5678

此特定值不包含重复字节,因此无法使用 memset 创建。

I can use the simple for loop to solve this problem

正确。

However, I think it is not very efficient to use for loop to set initial value for a such huge block

您可能会惊讶地发现编译器在优化循环方面的表现如此出色。有时他们用调用 memset 来替换循环(当结果相同时);有时它们会产生比调用 memset 更快的代码(好吧,至少在理论上是这样。编译器也知道 memset 的作用,并且还可以用从循环中生成的内联代码替换对它的调用,如果它认为它可能会更快)。

但是您不需要自己编写循环。正如 所示,标准库对此有一个算法。


1 需要注意的是,语言标准没有指定浮点类型的位表示,因此结果值在技术上可能是无意义的,甚至是陷阱表示。另一方面,IEEE 754 相当普遍,您可以根据用例依赖它。