如何将一个巨大的头部分配数组设置为特定的浮点数 C++
Posted
技术标签:
【中文标题】如何将一个巨大的头部分配数组设置为特定的浮点数 C++【英文标题】:How to set a huge head allocate array as specific float number C++ 【发布时间】:2020-06-10 13:39:43 【问题描述】:首先,我使用英特尔数学内核库 API 分配了一个巨大的块内存。之后,我想将此数组设置为特定值,例如 1234.5678。我打算用void* memset( void* dest, int ch, std::size_t count );
函数,但是这个函数好像只能设置int值。我可以使用简单的 for 循环来解决这个问题。但是,我认为使用for loop
为这么大的块设置初始值并不是很有效。所以我的问题是
-
我还有其他方法可以在不使用
for loop
的情况下初始化如此巨大的块内存吗?
【问题讨论】:
为了确保我理解,您想将 每个数组元素 的值设置为1234.5678
吗?如果是这样,您可能需要使用 std::fill
或 std::fill_n
为什么你认为 for 循环会低效。您是否尝试过并发现它太慢了?编译器非常擅长优化您编写的代码。基本上首选应该是写最直接的代码,让编译器为你做优化。
@john 如果要将值设置为某个整数,可以比较 memset 和 for 循环之间的性能。你会发现位操作要快得多。更重要的是,如果你使用for循环,你必须支付检查终止条件的成本。所以我只是想看看是否有其他方法可以做到这一点。
@CoryKramer 我认为这两个函数只适用于定义迭代器的包含。
@Sean 好吧,你说它是一个数组。语言指定了数组的迭代器。它是一个指针。
【参考方案1】:
您可以使用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
【讨论】:
我使用mkl分配内存,我认为不应该有迭代器。 @Sean 只要你有(或可以转换为)double*
,是一个迭代器【参考方案2】:
我打算使用 void* memset( void* dest, int ch, std::size_t count );函数,不过好像这个函数只能设置int值。
您实际上可以使用 memset 来设置 floats1 的值,或者实际上是任何可简单复制的类型。 int ch
只是将被复制到数据上的字节的值。
但这确实意味着您不能使用 memset 为多字节类型设置任意值,因为所有字节都会重复。例如,您可以将整数设置为 0,即四个 0 字节,或者将一个四字节整数设置为 4369,即四个 1 字节。
如果是符合 32 位 IEEE 754 的浮点数,您可以将 memset 设置为值 785.066650391F,例如,这样做:std::memset(ptr, count * sizeof(float), 0x44)
。这是因为该特定数字由四个重复的 0x44 字节组成。
具体值,例如 1234.5678
这个特定的值不包含重复的字节,所以不能用memset创建。
我可以使用简单的for循环来解决这个问题
正确。
但是,我认为使用for循环为这么大的块设置初始值并不是很有效
您可能会惊讶地发现编译器在优化循环方面有多出色。有时他们用调用 memset 替换循环(当它有相同的结果时);其他时候,它们会产生比调用 memset 更快的代码(好吧,至少在理论上。编译器也知道 memset 的作用,并且还可以用从循环中生成的内联代码替换对它的调用,如果它认为它可能会更快)。
但是,您不需要自己编写循环。正如Cory Kramer 所示,标准库对此有一个算法。
1 需要注意的是语言标准没有指定浮点类型的位表示,因此结果值在技术上可能是无意义的,甚至是陷阱表示。另一方面,IEEE 754 相当普遍,您可以根据用例依赖它。
【讨论】:
以上是关于如何将一个巨大的头部分配数组设置为特定的浮点数 C++的主要内容,如果未能解决你的问题,请参考以下文章