Skip to content

Commit 5686c8c

Browse files
authored
Improve element-wise tensor operation performance (#454)
transform_tensor previously used fplus::transform_convert, which calls reserve() and writes via a back_insert_iterator. Because push_back updates the vector's internal end pointer on every write, the compiler cannot auto-vectorize the loop. Switching to resize() with a plain random-access iterator allows GCC to emit SIMD instructions. Additionally, relu_layer now takes a fast path for the common standard ReLU case, using a simpler single-expression lambda that is easier to optimize than the general three-branch version. Combined effect: ~5% faster forward pass on VGG19.
1 parent 75f5610 commit 5686c8c

2 files changed

Lines changed: 14 additions & 4 deletions

File tree

include/fdeep/layers/relu_layer.hpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "fdeep/layers/activation_layer.hpp"
1010

1111
#include <algorithm>
12+
#include <limits>
1213
#include <string>
1314

1415
namespace fdeep {
@@ -30,14 +31,20 @@ namespace internal {
3031
protected:
3132
tensor transform_input(const tensor& in_vol) const override
3233
{
33-
auto activation_function = [&](float_type x) -> float_type {
34+
if (negative_slope_ == static_cast<float_type>(0) && threshold_ == static_cast<float_type>(0) && max_value_ == std::numeric_limits<float_type>::max()) {
35+
return transform_tensor([](float_type x) -> float_type {
36+
return std::max(static_cast<float_type>(0), x);
37+
},
38+
in_vol);
39+
}
40+
return transform_tensor([&](float_type x) -> float_type {
3441
if (x >= max_value_)
3542
return max_value_;
3643
if (threshold_ <= x && x < max_value_)
3744
return x;
3845
return negative_slope_ * (x - threshold_);
39-
};
40-
return transform_tensor(activation_function, in_vol);
46+
},
47+
in_vol);
4148
}
4249
float_type max_value_;
4350
float_type negative_slope_;

include/fdeep/tensor.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,10 @@ namespace internal {
190190
template <typename F>
191191
tensor transform_tensor(F f, const tensor& m)
192192
{
193-
return tensor(m.shape(), fplus::transform_convert<float_vec>(f, *m.as_vector()));
193+
const auto& src = *m.as_vector();
194+
float_vec result(src.size());
195+
std::transform(src.begin(), src.end(), result.begin(), f);
196+
return tensor(m.shape(), std::move(result));
194197
}
195198

196199
inline std::vector<tensor> tensor_to_depth_slices(const tensor& m)

0 commit comments

Comments
 (0)