This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Count number of logical processors sharing L2 cache


On Fri, May 13, 2016 at 6:36 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Wed, May 11, 2016 at 1:00 PM, H.J. Lu <hongjiu.lu@intel.com> wrote:
>> Tested on Intel processors with inclusive cache and non-inclusive cache.
>> OK for master?
>>
>>
>> H.J.
>> --
>>         * sysdeps/x86/cacheinfo.c (init_cacheinfo): Check and support
>>         non-inclusive caches on Intel processors.
>> ---
>>  sysdeps/x86/cacheinfo.c | 12 +++++++++++-
>>  1 file changed, 11 insertions(+), 1 deletion(-)
>>
>> diff --git a/sysdeps/x86/cacheinfo.c b/sysdeps/x86/cacheinfo.c
>> index 143b333..8408624 100644
>> --- a/sysdeps/x86/cacheinfo.c
>> +++ b/sysdeps/x86/cacheinfo.c
>> @@ -492,6 +492,9 @@ init_cacheinfo (void)
>>      {
>>        data = handle_intel (_SC_LEVEL1_DCACHE_SIZE, max_cpuid);
>>
>> +      long int core = handle_intel (_SC_LEVEL2_CACHE_SIZE, max_cpuid);
>> +      bool inclusive_cache = true;
>> +
>>        /* Try L3 first.  */
>>        level  = 3;
>>        shared = handle_intel (_SC_LEVEL3_CACHE_SIZE, max_cpuid);
>> @@ -500,7 +503,7 @@ init_cacheinfo (void)
>>         {
>>           /* Try L2 otherwise.  */
>>           level  = 2;
>> -         shared = handle_intel (_SC_LEVEL2_CACHE_SIZE, max_cpuid);
>> +         shared = core;
>>         }
>>
>>        /* Figure out the number of logical threads that share the
>> @@ -526,6 +529,9 @@ init_cacheinfo (void)
>>             }
>>           while (((eax >> 5) & 0x7) != level);
>>
>> +         /* Check if cache is inclusive of lower cache levels.  */
>> +         inclusive_cache = (edx & 0x2) != 0;
>> +
>>           threads = (eax >> 14) & 0x3ff;
>>
>>           /* If max_cpuid >= 11, THREADS is the maximum number of
>> @@ -592,6 +598,10 @@ init_cacheinfo (void)
>>          threads.  */
>>        if (shared > 0 && threads > 0)
>>         shared /= threads;
>> +
>> +      /* Account for non-inclusive L2 and L3 caches.  */
>> +      if (level == 3 && !inclusive_cache)
>> +       shared += core;
>>      }
>>    /* This spells out "AuthenticAMD".  */
>>    else if (is_amd)
>> --
>> 2.5.5
>>
>
> I will check it in today.
>

We need count number of available logical processors sharing L2
cache.


-- 
H.J.
From 9a39358a353ff1906c728096bb343bb31a850d6c Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Fri, 13 May 2016 13:26:37 -0700
Subject: [PATCH] Count number of logical processors sharing L2 cache

For Intel processors, we should count number of available logical
processors sharing L2 cache for non-inclusive L2 and L3 caches.

	* sysdeps/x86/cacheinfo.c (init_cacheinfo): Count number of
	available logical processors sharing L2 cache for Intel
	processors.
---
 sysdeps/x86/cacheinfo.c | 30 +++++++++++++++++++++++++++++-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/sysdeps/x86/cacheinfo.c b/sysdeps/x86/cacheinfo.c
index 8408624..6fe41be 100644
--- a/sysdeps/x86/cacheinfo.c
+++ b/sysdeps/x86/cacheinfo.c
@@ -499,12 +499,18 @@ init_cacheinfo (void)
       level  = 3;
       shared = handle_intel (_SC_LEVEL3_CACHE_SIZE, max_cpuid);
 
+      /* Number of logical processors sharing L2 cache.  */
+      int logical_threads_l2;
+
       if (shared <= 0)
 	{
 	  /* Try L2 otherwise.  */
 	  level  = 2;
 	  shared = core;
+	  logical_threads_l2 = -1;
 	}
+      else
+	logical_threads_l2 = 0;
 
       /* Figure out the number of logical threads that share the
 	 highest cache level.  */
@@ -526,6 +532,11 @@ init_cacheinfo (void)
 		 assume there is no such information.  */
 	      if ((eax & 0x1f) == 0)
 		goto intel_bug_no_cache_info;
+
+	      /* Get maximum number of logical processors sharing L2
+		 cache.  */
+	      if (logical_threads_l2 == 0 && ((eax >> 5) & 0x7) == 2)
+		logical_threads_l2 = (eax >> 14) & 0x3ff;
 	    }
 	  while (((eax >> 5) & 0x7) != level);
 
@@ -551,6 +562,19 @@ init_cacheinfo (void)
 		  int type = ecx & 0xff0;
 		  if (shipped == 0 || type == 0)
 		    break;
+		  else if (type == 0x100)
+		    {
+		      if (logical_threads_l2 > 0)
+			{
+			  int count_mask;
+
+			  /* Compute count mask.  */
+			  asm ("bsr %1, %0"
+			       : "=r" (count_mask) : "g" (threads));
+			  count_mask = ~(-1 << (count_mask + 1));
+			  logical_threads_l2 = (shipped - 1) & count_mask;
+			}
+		    }
 		  else if (type == 0x200)
 		    {
 		      int count_mask;
@@ -601,7 +625,11 @@ init_cacheinfo (void)
 
       /* Account for non-inclusive L2 and L3 caches.  */
       if (level == 3 && !inclusive_cache)
-	shared += core;
+	{
+	  if (logical_threads_l2 > 0)
+	    core /= (logical_threads_l2 + 1);
+	  shared += core;
+	}
     }
   /* This spells out "AuthenticAMD".  */
   else if (is_amd)
-- 
2.5.5


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]