dec*_*iar 15 c++ optimization const
在分析我的反向传播算法后,我了解到它负责占用我60%的计算时间.在我开始研究并行替代方案之前,我想看看我能做些什么.
该activate(const double input[])功能仅被占用约5%的时间.该gradient(const double input)功能实现如下:
inline double gradient(const double input) { return (1 - (input * input)); }
Run Code Online (Sandbox Code Playgroud)
有问题的培训功能:
void train(const vector<double>& data, const vector<double>& desired, const double learn_rate, const double momentum) {
this->activate(data);
this->calculate_error(desired);
// adjust weights for layers
const auto n_layers = this->config.size();
const auto adjustment = (1 - momentum) * learn_rate;
for (size_t i = 1; i < n_layers; ++i) {
const auto& inputs = i - 1 > 0 ? this->outputs[i - 1] : data;
const auto n_inputs = this->config[i - 1];
const auto n_neurons = this->config[i];
for (auto j = 0; j < n_neurons; ++j) {
const auto adjusted_error = adjustment * this->errors[i][j];
for (auto k = 0; k < n_inputs; ++k) {
const auto delta = adjusted_error * inputs[k] + (momentum * this->deltas[i][j][k]);
this->deltas[i][j][k] = delta;
this->weights[i][j][k] += delta;
}
const auto delta = adjusted_error * this->bias + (momentum * this->deltas[i][j][n_inputs]);
this->deltas[i][j][n_inputs] = delta;
this->weights[i][j][n_inputs] += delta;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这个问题可能更适合https://codereview.stackexchange.com/.对于那些感兴趣的人,可以在这里找到最小编译所需的代码:Backprop.cpp.
如果要训练/使用NN,则无法避免使用O(n ^ 2)算法.但它非常适合矢量运算.例如,通过巧妙地使用SSE或AVX,您可以处理4或8块的神经元,并使用乘法加法而不是两个单独的指令.
如果您使用的现代编译器和仔细重新制定的算法,并使用正确的开关,你甚至可以让编译器autovectorize环路你,但你的里程可能会有所不同.
对于gcc,使用-O3或-ftree-vectorize激活自动向量化.你需要一个支持向量的cpu,比如-march = core2 -mssse4.1或类似的,具体取决于目标cpu.如果你使用-ftree-vectorizer-verbose = 2,你会得到详细的解释,为什么和哪里的循环没有矢量化.看看http://gcc.gnu.org/projects/tree-ssa/vectorization.html.
更好的是当然直接使用编译器内在函数.