Quick sorting of GNU glibc qsort_r

Source: Internet
Author: User

 

Today, I re-read the source code for fast sorting in glibc ~ I have some different understandings. Why is this articleArticleDelayed

Publishing is also because I do not have a deep understanding of the source code, and I don't feel quite clear about it. Today I found some information and carefully figured out the source code.

Code, simply write it out. If anything is missing, please criticize and correct it ~

 

Previously, I always thought that the source code in glibc would be expensive.CodeGeneral processing, but after browsing again today, I found myself

Wrong ~ But I am still very happy. After all, I am still young ~

 

In fact, the source code for fast sorting in glibc focuses on extracting CPU performance and improving the execution efficiency of fast sorting. Why is it extracted? Because

The source code is truly efficient.

1/*For large object sizes use Indirect sorting.*/2If(S>32)3Size =2* N *Sizeof(Void*) + S; // Why is the 2n + 1 space calculated here?

 

See the preceding English comments. The source code also classifies the Quick Sort in different ways. This means that if a single element

If the length is greater than 32 bytes, it is regarded as a large object and indirect sorting is adopted. What does indirect sorting mean? Let's talk about it later.

 

I don't know if my colleagues don't understand Why sizeof (void *) is required. Well, I can only say that my head is always awkward.

Let's take a look back at the qsort_r function declaration.

1 Void2Qsort_r (Void* B, size_t N, size_t S, _ compar_d_fn_t CMP,Void* Arg)

 

We can clearly see that the type of the target array parameter is declared as void *, so here we need to calculate the size of the required storage space. Then contact

The two sorting methods used in the source code are indirect fast sorting and direct quick sorting. If you select the sorting method by element size alone, it is not reliable.

Why? Even if the elements occupy a large amount of space, but the number of elements is very small, the indirect sorting is not allowed.

The length is the most reliable basis. (correction, in fact, refers to the length of the pointer. Can you tell me the error? The majority of students .-,-)

1If(Size <1024)2/*The temporary array is small, so put it on the stack.*/3P. t = _ alloca (size );

Therefore, the above Code can describe everything.

 

_ What is alloca? Let's take a look ~ It is a macro:

 
1 # Ifdef _ gnuc __2 # DEFINE _ alloca (size) _ builtin_alloca (size)3 # Endif/* GCC .*/

This is a function implementation exclusive to GCC. I have read a lot of documents. The manual says that _ builtin_alloca is a private implementation version.

I have not provided any other instructions. I have not found any other materials. If you know anything, please let me know ~

 

These codes tell us that if the target array length is less than 1024 bytes, direct and fast sorting is used; otherwise, indirect and fast sorting is used.

 
1If(Size/pagesize>(Size_t) phys_pages)2 {3 _ Quicksort (B, N, S, CMP, ARG );4Return;5}

 

Skip the previous sections of code and look at the above section of code. Here we call direct and fast sorting. We do not care about the implementation of direct sorting,

First, let's see why direct sorting is called. Pay attention to the conditions. To understand the conditions, you need to look at the code ignored in the previous section.

 1         /* We shoshould avoid allocating too much memory since this might  2   Have to be backed up by swap space.  */  3         Static   Long   Int  Phys_pages;  4         Static   Int  Pagesize;  5   6         If (Pagesize = 0  )  7   {  8 Phys_pages = _ Sysconf (_ SC _phys_pages );  9   10         If (Phys_pages =- 1  )  11           /*  Error while determining the memory size. So let's  12  Assume there is enough memory. Otherwise  13   Implementer shocould provide a complete implementation  14   The 'sysconf' function.  */  15 Phys_pages = ( Long   Int )(~ 0ul > 1  );  16   17        /*  The following determines that we will never use more  18   A quarter of the physical memory.  */  19 Phys_pages/= 4  ;  20   21         /*  Make sure phys_pages is written to memory.  */  22   Atomic_write_barrier (); 23   24 Pagesize = _ sysconf (_ SC _pagesize)

 

The functions involved in this Code are complex and will not be explained in detail in this article.

Physical available memory parameters. The most important thing is to avoid using swap space, because doing so will reduce the sorting efficiency.

 

After a brief explanation of this Code, the previous conditions are clear. If the available memory of the system is sufficient, allocate resources from the heap.

The memory uses indirect and fast sorting. If not enough, you have to directly sort it. That is, you can directly call the _ quicksort function.

 1         Int Save = Errno;  2 TMP = Malloc (size );  3   _ Set_errno (SAVE ); 4         If (TMP = Null)  5   {  6         /*  Couldn't get space, so use the slower Algorithm  7   That doesn't need a temporary array.  */  8   _ Quicksort (B, N, S, CMP, ARG );  9         Return ;  10   }  11 P. t = TMP;

Use the malloc function to allocate the required memory space from the heap. If the memory space cannot be allocated (there are many reasons for unallocation), indirect and fast sorting is still used.

If the memory is allocated, put the space address pointer into a struct. Let's look at this struct:

  1   struct   msort_param   2  {  3   size_t s;   4  size_t  var  ;   5   _ compar_d_fn_t CMP;   6   void  *  ARG;   7   char  *  T;   8 }; 
1P.s =S;2P.VaR=4;3P. CMP =CMP;4P. Arg = ARG;

 

The following initialization source code initializes the members in P. It compares the previous struct declaration with the types of parameters.

 1   If (S> 32  ) // If the length of a single element is greater than 32  2   {  3         /* Indirect sorting.  */  4         Char * IP = ( Char * ) B; // obtain the address of the target array.  5         Void ** TP = ( Void **) (P. t + N * Sizeof ( Void * ); // Obtain the position pointer of the sorting space N + 1.  6         Void ** T =TP;  7         Void * Tmp_storage = ( Void *) (TP + N); // the last position of the sorting Space The requested space is 2n + 1.
 8 // Note why void * is used here, because indirect sorting sorts pointers rather than elements. 9         While (( Void *) T < Tmp_storage)  10   {  11 * T ++ =IP address; // copy pointer.  12 IP + = S; // move to the next pointer. Because the type is byte, shift according to the element length.  13   }  14 P.s = Sizeof ( Void * );  15 P. VaR = 3  ;  16 Msort_with_tmp (& P, P. t + N *Sizeof ( Void * ), N );  17   18         /*  TP [0] .. TP [n-1] is now sorted, copy around entries  19   The original array. knuth Vol. 3 (2nd ed.) exercise 5.2-10.  */  20         Char * KP;  21   Size_t I; 22         For (I = 0 , IP = ( Char *) B; I <n; I ++, IP + = S)  23       If (Kp = TP [I])! = IP)  24   {  25 Size_t J = I;  26           Char * JP = IP address; 27   Memcpy (tmp_storage, IP, S );  28   29           Do  30   {  31 Size_t k = (Kp -( Char *) B )/ S;  32 TP [J] = JP;  33   Memcpy (JP, KP, S );  34 J =K;  35 JP = KP;  36 Kp = TP [k];  37   }  38           While (KP! = IP );  39   40 TP [J] = JP;  41   Memcpy (JP, tmp_storage, S ); 42   }  43   }  44     Else  45   {
// The following source code is useless. It is mainly used to initialize P. var according to the conditions. 46 If (S &( Sizeof (Uint32_t )- 1 ) = 0 47 &&(( Char *) B -(Char *) 0 ) % _ Alignof _ (uint32_t) = 0 ) 48 { 49 If (S = Sizeof (Uint32_t )) 50 P. VaR = 0 ; 51 Else If (S = Sizeof (Uint64_t) 52 &&(( Char *) B -( Char *) 0 ) % _ Alignof _ (uint64_t) = 0 ) 53 P. VaR = 1 ; 54 Else If (S &( Sizeof (Unsigned Long )- 1 ) = 0 55 &&(( Char *) B -( Char *) 0 ) 56 % _ Alignof _ (unsigned Long ) = 0 ) 57 P. VaR = 2 ; 58 } 59 Msort_with_tmp (& P, B, n ); 60 } 61 Free (TMP );

As described in the preceding annotations, a large piece of code initializes the VaR value in P according to the conditions. In the source code, we can see that,

P. var has four values, 0, 1, 3, and so on. What do they mean? To go to the source code of the msort_with_tmp Function

Just look at it to know. Similarly, if you want to understand how to do it in indirect and fast sorting, you should also look at it.

 

the following analysis will be continued in the next article. Please handle the problem ~

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.