如何将巨大的头部分配数组设置为特定的浮点数 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
为这么大的块设置初始值并不是很有效。所以我的问题是
- 我有没有另一种方法可以在不使用
for loop
的情况下初始化这么大的块内存
您可以使用 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 相当普遍,您可以根据用例依赖它。
起初,我使用Intel Math Kernel Library分配了一个巨大的块内存API。之后我想将此数组设置为特定值,例如 1234.5678。我打算用void* memset( void* dest, int ch, std::size_t count );
这个函数,但是好像这个函数只能设置int值。我可以使用简单的 for 循环来解决这个问题。但是,我认为使用 for loop
为这么大的块设置初始值并不是很有效。所以我的问题是
- 我有没有另一种方法可以在不使用
for loop
的情况下初始化这么大的块内存
您可以使用 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 相当普遍,您可以根据用例依赖它。