使用闪电速度缩放值数组

Scale an array of values with lightning speed

本文关键字:缩放 数组 速度      更新时间:2023-10-16

我有一个包含12000个条目的double数组。我需要按因子(例如0.3345或6.78)缩放每个条目的值。不管怎样)。

我所做的是循环每个条目并进行乘法运算。当我在一个基于PPC的100MHz嵌入式系统上工作时,大量的乘法调用大大降低了速度。

我有办法做得更快。一个类比就像初始化一个内存块一样——使用非常快的memset。我想知道是否有等效的方法。

我想回答一个问题:您真的需要来实际乘以每个值吗?

就我个人而言,我会考虑使用一个更好的数据结构,它将数组的实际内容隐藏在一个私有变量中,并提供一个只更新scale-字段的缩放函数。然后,数据结构的公共访问方法可以在每个需求的基础上根据缩放字段简单地缩放值。

memset速度非常快是有原因的:它不依赖于内存的前一个值。这不是你的情况。

你的问题有几个解决办法。第一种是改变算法,这样就可以防止第一种情况下的乘法运算。这就是我拍摄的目的。一个例子是包装数组,该数组在访问元素时与元素相乘。

如果无法避免数据中的乘法运算,最好将乘法运算并行化,将数组分为n部分(其中n等于处理器数量),其中每个部分都分配给一个线程进行乘法运算。这是一个例子:

void multiply_block(double *array, const double val, const size_t len) {
    int n = (len + 7) / 8;
    /* duff's device */
    switch (len % 8) {
        case 0:      do {    *array++ *= val;
        case 7:              *array++ *= val;
        case 6:              *array++ *= val;
        case 5:              *array++ *= val;
        case 4:              *array++ *= val;
        case 3:              *array++ *= val;
        case 2:              *array++ *= val;
        case 1:              *array++ *= val;
                     } while(--n > 0);
    }
}
void multiply_block_parallel(double *array, const double val, const size_t len) {
    const int threads = get_num_processors();
    int i = 0;
    /* start all but the last thread */
    while (i < (threads - 1)) {
        start_thread(multiply_block,
                     array + i * (len / threads), val,  len / threads);
        i++;
    }
    /* start last thread with remaining data */
    start_thread(multiply_block,
                 array + i * (len / threads), val, len - i * (len / threads));
}

在本例中,get_num_processors返回处理器的数量,而start_thread(func, args...)是一个函数,它启动一个新线程,用给定的参数执行func。显然,您应该用现实生活中的等效功能来替换这些功能。

首先,如果可以的话,我建议您考虑使用固定点,将任务简化为整数乘法将大大提高性能。

在这种情况下,你可以预先计算一个"乘法表"。因此,假设你想乘以很多x<256个数字乘以3,您将生成:

  1 * 3 = 3
  2 * 5 = 6
  4 * 3 = 12
  8 * 3 = 24
 16 * 3 = 48
...
128 * 3 = 384

它甚至非常快,因为你只需要将结果一个接一个地向左移动。然后,对于每个需要相乘的元素,取最后一位,将相应的数字与表中的结果相加,然后将值向右移动。这样你就可以把乘法简化为8个加法。