IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

数组的优化循环展开与分割

搜索技术博客-淘宝 2010-12-29 09:11:12 累计浏览 3,477 次
本机暂存

    数组的循环与分割, 利用了计算机系统的两个特点:

    1. 有多块高速缓存;

    2. Cpu是可以多指令并行执行(要求多条指令之间 没有数据相关性)。

    在我们的例子中:

    数组切分: 将1个数组切分为2个数组。 这样就能用2块高速缓存来存数据 , 高速缓存的访问速度是内存的 10倍以上

    循环展开: 我们将的步进设置为4,每次处理的数据之间 没有任何关系,这样就能并行执行起来。

    数据无关性: 就是下一次计算指令不受之前执行指令的结果影响。在我们的例子里面, 将对 i 的操作 提到前面, 这样后面的赋值操作和i没有关系,我们再赋值的时候同时可以进行 下一次循环了。

/**
 * 批量追加 docId 到结尾
 * @param thiz
 * @param docId_arr   docid 的数组
 * @param num         数组元素个数
 * @return
 */
Ret docArray_batch_append(DocArray* thiz, UINT_32 docId_arr[], int num)
{
    return_val_if_fail(thiz != NULL && num > 0, RET_INVALID_PARAMS);
    if (LIKELY(docArray_expand(thiz, num) == RET_OK))
    {
        register int  size = thiz->size;
        register int  i    = 0;
        register int  i1   = 0;
        register int  i2   = 0;
        register int  i3   = 0;
        // 去掉后2位
        register int  bn   = (num >> 3) << 2;
        // 做循环分割和循环展开
        DOC*     data       = &(thiz->data[size]);
        // 取其中的一半, 切分成2个数组
        DOC*     data2      = &(data[bn]);
        UINT_32* docId_arr2 = &(docId_arr[bn]);
        for (i = 0; LIKELY(i < bn); i = i + 4)
        {
            data[i].docId   = docId_arr[i];
            // 特意提到前面后续的操作和i没有关系,提高并行度。
            data2[i].docId  = docId_arr2[i];
            i1 = i + 1;
            i2 = i + 2;
            i3 = i + 3;
            data[i1].docId  = docId_arr[i1];
            data[i2].docId  = docId_arr[i2];
            data[i3].docId  = docId_arr[i3];
            data2[i1].docId = docId_arr2[i1];
            data2[i2].docId = docId_arr2[i2];
            data2[i3].docId = docId_arr2[i3];
        }
        for (i = (bn << 1); i < num; ++i)
        {
            data[i].docId = docId_arr[i];
        }
        thiz->size = size + num;
    }
    return RET_OK;
}

同分类推荐文章

  1. 对基本有序的序列排序算法 (2026-06-11 17:46:49)
  2. Four Levels Of Customer Understanding (2026-05-22 21:00:00)
  3. 除法的意义 (2026-04-12 20:52:17)

查看更多 算法 文章 →

建议继续学习

  1. 30分钟3300%性能提升――python+memcached网页优化小记 (累计阅读 13,741)
  2. Linus:为何对象引用计数必须是原子的 (累计阅读 12,292)
  3. 使用memc-nginx和srcache-nginx构建高效透明的缓存机制 (累计阅读 7,142)
  4. 使用 Perl 中的 Gearman来实现 MapReduce (累计阅读 3,995)
  5. 讨论:一则并行聚合计算方案的设计 (累计阅读 2,343)