【问题标题】:Can I put this division out?我可以把这个部门拿出来吗?
【发布时间】:2020-07-03 01:42:42
【问题描述】:

我正在编写一个执行大量操作的应用程序,并且我正在尝试尽可能多地进行优化。

我试图将除法 (31 / sum) 放在 test2 之外,因为这样我可以在一个循环中只执行 1 次操作,否则会执行 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;
    }

谢谢。

【问题讨论】:

  • 这不是无效的吗? unsigned char test = 555; 在大多数机器上 char 是 1 个字节。我也没有看到任何循环。你能展示更多的代码吗?
  • 31 / sum31 / 1234 始终是0
  • 看来是有效的。正如我上面写的那样,该程序是给我的。它必须返回与原始值相同的值。
  • 你想达到什么目的?给我们看一个现实的例子。您的示例值不适合无符号字符,因此我们在这里处理的不是 1234 和 555,而是值 43 和 210。如果我们假设整数,test2 的值在两种情况下是不同的。
  • unsigned sum = ua + ub + uc + ud + 1; sum /= 31; unsigned_char_array_a[i] = ua / sum; 更接近。需要深思。

标签: c char integer unsigned


【解决方案1】:

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 以内。

【讨论】:

  • 这有效并节省了一些毫秒,但错误尽管小到 1,但会累积,最终结果与预期不同。
猜你喜欢
  • 2021-08-23
  • 2020-04-24
  • 1970-01-01
  • 1970-01-01
  • 2012-05-11
  • 2021-02-03
  • 1970-01-01
  • 2013-05-17
  • 1970-01-01
相关资源
最近更新 更多