message: Fold division in uint8 log softmax to outside for loop.
diff: @@ -3643,8 +3643,6 @@ inline void LogSoftmax(const SoftmaxParams& params,
  // TODO(tflite): notes for optimization:
  // 1) See if e^ is also bottleneck in the reference fully-integer
  // version and apply lookup there and compare.
  -// 2) Time spent is currently split between computing max_val, the
  -// rint call, and the computation of log_prob.
  inline void LogSoftmax(const SoftmaxParams& params, float input_scale,
  const RuntimeShape& input_shape, const uint8* input_data,
  const RuntimeShape& output_shape, uint8* output_data) {
  @@ -3675,17 +3673,19 @@ inline void LogSoftmax(const SoftmaxParams& params, float input_scale,
  }
  const float log_sum_exp = std::log(sum_exp);
  - const float precomputed = input_scale * max_val + log_sum_exp;
  + // params.scale is the output scale.
  + const float scale = input_scale / params.scale;
  + const float precomputed =
  + (input_scale * max_val + log_sum_exp) / params.scale;
  for (int j = 0; j < last_dim; ++j) {
  - // Equivalent to input_scale * (input_data[j] - max_val) - log_sum_exp;
  - const float log_prob = input_scale * input_data[j] - precomputed;
  + // Equivalent to (input_scale * (input_data[j] - max_val) - log_sum_exp) /
  + // output_scale.
  + const float log_prob = scale * input_data[j] - precomputed;
  // TODO(tflite): look into better solution.
  // Use std::rint over std::round (which is used in
  // FakeQuant) since it's multiple times faster on tested arm32.
  - const int32_t prob_quantized =
  - std::rint(log_prob / params.scale) + params.zero_point;
  -
  + const int32_t prob_quantized = std::rint(log_prob) + params.zero_point;
  output_data[j] = static_cast<uint8_t>(
  std::max(std::min(clamp_max, prob_quantized), clamp_min));
  }
  