Могу ли я положить это разделение? - PullRequest
0 голосов
/ 22 марта 2020

Я программирую приложение, которое выполняет огромное количество операций, и пытаюсь максимально оптимизировать его.

Я пытаюсь поместить деление (31 / сумма) вне test2, потому что таким образом я мог бы выполнить операцию только 1 раз за один l oop, в противном случае это делается 3 раза.

unsigned sum = 1234;
unsigned char test = 555;
unsigned char test2 = test * 31 / sum;

Цель будет

unsigned sum = 1234;
unsigned char test = 555;
unsigned division = 31 / sum;
unsigned char test2 = test * division;

Пример реального случая (упрощенно) в C:

for (int i = 0; i < N; i++)
    {
        unsigned a=0,b=0,c=0,d=0;
        int aux;

        for (int j = 0; j < M; j++)
        {
            aux = arr[j];
            if (conditions)
                a += aux;
            if (conditions)
                b += aux;
            if (conditions)
                c += aux;
            if (conditions)
                d += aux;
        }

        unsigned char ua = a, ub = b, uc = c, ud = d;
        unsigned sum = ua + ub + uc + ud + 1;
        unsigned_char_array_a[i] = ua * 31 / sum;
        unsigned_char_array_b[i] = ub * 31 / sum;
        unsigned_char_array_c[i] = uc * 31 / sum;
        unsigned_char_array_d[i] = ud * 31 / sum;
    }

Спасибо.

1 Ответ

1 голос
/ 22 марта 2020

OP, похоже, хочет избежать целочисленного деления - чего-то, в чем некоторые (встроенные) процессоры работают медленно - даже при том, что они имеют быстрое умножение.

  // 4 divisions.
  unsigned sum = ua + ub + uc + ud + 1;
  unsigned_char_array_a[i] = ua * 31 / sum;
  unsigned_char_array_b[i] = ub * 31 / sum;
  ...

Учитывая, что sum будет иметь значение в [ 1-1021], код может выполнять масштабированное умножение, а затем деление на постоянную степень-2. Хорошие компиляторы сделают простой быстрый переход. С 32-битным int/unsigned:

Масштабирование по 65536

  #define SCALE 65536u

  unsigned factor = (31 * SCALE)/sum;
  unsigned_char_array_a[i] = (ua * factor) / SCALE;
  unsigned_char_array_b[i] = (ub * factor) / SCALE;
  ...

Непроверенное утверждение: я не ожидаю точно такого же отношения каждый раз, как (ua * 31) / sum;, но будет в пределах 1 .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...