【发布时间】:2017-11-13 04:54:23
【问题描述】:
我正在尝试自学如何编写更快的代码(使用更少指令的代码)。我想创建一个人工神经网络(ANN)。如果您对人工神经网络一无所知,您仍然可以帮助我,因为我的问题更多地涉及编写比人工神经网络更快的代码。基本上,我将有一大堆双打,我需要在上面进行大量数学运算。我可以像这样分配我的数组:
class Network {
double *weights;
double *outputs;
public:
Network()
{
}
Network(int * sizes, int numofLayers)
{
int sum = 0;
int neuron_count = 0;
// this just ensures my weight array is the right size
for(int i = 0; i < numofLayers-1; i++)
{
neuron_count += sizes[i];
sum = sum + sizes[i]*sizes[i+1];
}
neuron_count += sizes[numofLayers-1];
weights = new double[sum];
outputs = new double[neuron_count];
}
~Network()
{
delete[] weights;
delete[] outputs;
}
};
但是,我不喜欢这个,因为我使用“new”,而且我知道我以后可能会遇到一堆内存管理问题。我知道堆栈分配更快,如果我可以根据这段摘录提供帮助,我不应该使用动态内存:
"动态内存分配是由操作符 new 和 delete 完成的 或使用 malloc 和 free 函数。这些运算符和函数 消耗大量时间。内存的一部分称为堆 保留用于动态分配。堆很容易变成 分配不同大小的对象时碎片化 以随机顺序释放。堆管理器可以花很多时间 清理不再使用的空间并寻找空置空间 空格。这称为垃圾收集。分配的对象 in sequence 不一定按顺序存储在内存中。他们 当堆变成 支离破碎。这使得数据缓存效率低下”
在 C++ 中优化软件 Windows、Linux 的优化指南 和 Mac 平台 作者:Agner Fog。
但是,我想在类 Network 中创建的许多函数将使用数组权重和输出;如果它们是本地的并且被释放,那将不起作用。我觉得要么使用 new 关键字,要么只为几乎整个神经网络创建一个巨大的函数。
在正常情况下,我会说可读性对于保持代码更重要,但我并不担心,因为这更多地是为了学习编写快速代码。如果为耗时的算法编写代码的人编写大函数以使事情变得最快,那很好。我只是想知道。
另一方面,如果我的数组只分配一次并且将在整个程序中使用,那么使用堆分配是否更聪明,因为有问题的开销应该只发生一次?然后专注于在数学繁重的代码中使用内在函数或其他东西。是否还有其他缺点,例如,如果我经常访问堆以便将内存移动到缓存中,这是否比访问堆栈上的内存更密集,以便将堆栈移动到缓存(即使堆应该保持不变)?写得非常快的代码的人总是绝对避免使用新的吗?如果是这样,我有什么替代方法可以以这种方式组织我的程序,并且仍然保持我的数组为用户指定的任意大小?
【问题讨论】:
-
你不需要使用
new。只需使用std::vector。 -
继续您的设计。在设计级别进行优化,优化将流向实施。删除不必要的循环。数据缓存优化设计。执行缓存优化设计。
-
更快的代码 != 更少的指令 通常是这样,但是更好地组织数据结构,即使需要更多的代码,也会带来惊人的性能提升。
-
推荐阅读What is The Rule of Three?,因为你的班级违反了它。以上
std::vector的推荐,瞬间解决了这个问题。 -
您不需要也不想要手动内存管理。 至少使用智能指针。更好的是,只需使用
std::vector或std:array。
标签: c++ arrays memory optimization memory-management