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

转自:http://www.searchtb.com/2010/12/array-loop-optimization.html

数组的循环与分割, 利用了计算机系统的两个特点:
1. 有多块高速缓存;
2. Cpu是可以多指令并行执行(要求多条指令之间 没有数据相关性)。

在我们的例子中:
数组切分: 将1个数组切分为2个数组。 这样就能用2块高速缓存来存数据 , 高速缓存的访问速度是内存的 10倍以上
循环展开: 我们将的步进设置为4,每次处理的数据之间 没有任何关系,这样就能并行执行起来。
数据无关性: 就是下一次计算指令不受之前执行指令的结果影响。在我们的例子里面, 将对 i 的操作 提到前面, 这样后面的赋值操作和i没有关系,我们再赋值的时候同时可以进行 下一次循环了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/**
  * 批量追加 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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值