简体   繁体   中英

C code - memory access / preemption

I have written a piece of code wherein a data:

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

I am adding up the i/p data for every 3 contiguous bytes and storing the ans. ex: temp[4096]; temp[0] = buf[0] + buf[1] + buf[2]; ... till 4096

Then a histogram is generated from the results of temp using the code:

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

The histogram is sorted (bubble sort) and then top 8 most recurring values are taken. The code is run in the linux kernel (2.6.35)

The problem I am facing is that if I remove the sorting part, the time taken to execute the code is very fast (6 microsec on my laptop, measured using gettimeofday func). But after introducing the sorting, the process slows down to a great extent (44 microsec). The sorting function itself takes 20 microsecs, I cant understand why is the time then increasing so much. I did a memory analysis using cachegrind, the results are normal and I even tried disabling preemption ubut still it doesnt show any difference. If anybody can help me out over here. Thanks!

Bubble sort is slow, it compares and swaps your values up to 4096*4096 = 16,777,216 times. If you need only the 8 best values, a 1 sweep selection is certainly faster. Something like that.

 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. */
   }
 }

With that, you compare your values only once and the cost of the memmove is negligible because your selection array is small. No need to sort the array, this algo is O(nm) with n the size of your array and m the size of your selection. The best sort would be O((n.log2 n).m). So if m is small and n is big, it is unbeatable by any generic sort algorithm.

EDIT : I added the array for the index.

EDIT2 : Introduced second to correct the fundamental bug I had in first instance.

EDIT3 : Comment: memmove with size 0 is allowed and is basically a nop.

Bubble sort is slow... O(N^2) complexity... if you want faster performance, use a data-structure like a heap, or run the quick-sort algorithm on your array, both of which will give you O(N log N) complexity for the sorting process. In addition, both methods will also work nicely on fixed-length arrays.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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