繁体   English   中英

C 代码 - memory 访问/抢占

[英]C code - memory access / preemption

我写了一段代码,其中有一个数据:

unsigned char buf[4096]; // data in chunks of size 4k
unsigned counter[256];

我将每 3 个连续字节的 i/p 数据相加并存储 ans。 例如:温度[4096]; 临时[0] = buf[0] + buf[1] + buf[2]; ... 直到 4096

然后使用以下代码从 temp 的结果生成直方图:

for(i = 0; i < 4096; i++)
counter[temp[i]]++;

对直方图进行排序(冒泡排序),然后取前 8 个最常出现的值。 代码运行在 linux kernel (2.6.35)

我面临的问题是,如果我删除排序部分,执行代码所需的时间非常快(在我的笔记本电脑上为 6 微秒,使用 gettimeofday func 测量)。 但是在引入排序之后,这个过程在很大程度上减慢了(44微秒)。 排序 function 本身需要 20 微秒,我不明白为什么时间会增加这么多。 我使用 cachegrind 进行了 memory 分析,结果正常,我什至尝试禁用抢占,但仍然没有显示任何差异。 如果有人可以在这里帮助我。 谢谢!

冒泡排序很慢,它比较和交换您的值高达 4096*4096 = 16,777,216 次。 如果您只需要 8 个最佳值,那么选择 1 个扫描肯定会更快。 类似的东西。

 const uint_t n = 8;
 uint_t best[n] = {0};
 uint_t index[n] = {0};
 uint_t j;

 for(uint_t i=0; i<4096; i++) {

   if(counter[i] > best[n-1]) {
     for(j=n-2; j && counter[i] > best[j]; j--);           /* Find the insertion position, as our value might be bigger than the value at position n-1. */
     memmove(&best [j+1], &best[j] , (n-1 -j) * sizeof best[0]);      /* Shift the values beyond j up 1  */
     memmove(&index[j+1], &index[j], (n-1 -j) * sizeof index[0]);
     best[j] = counter[i];                                 /* Put the current best value at the top */
     index[j] = i;                                         /* Store the index in the second array to know where the best value was. */
   }
 }

这样,您只需比较一次您的值,并且memmove的成本可以忽略不计,因为您的选择数组很小。 无需对数组进行排序,此算法为 O(nm),其中 n 是数组的大小,m 是您选择的大小。 最好的排序是 O((n.log2 n).m)。 因此,如果 m 小而 n 大,任何通用排序算法都无法击败它。

编辑:我为索引添加了数组。

EDIT2 :引入第二个以纠正我在第一个实例中遇到的基本错误。

EDIT3 :评论:允许使用大小为 0 的memmove ,基本上是一个 nop。

冒泡排序很慢... O(N^2) 复杂度...如果您想要更快的性能,请使用像堆这样的数据结构,或者在您的数组上运行快速排序算法,这两者都会给您 O (N log N) 排序过程的复杂度。 此外,这两种方法也适用于固定长度的 arrays。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM