mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-08-12 03:39:01 +08:00
default to Intel's API by default
This commit is contained in:
parent
e1a6bad087
commit
546587c7d3
@ -599,6 +599,52 @@ public:
|
|||||||
# define EIGEN_CPUID(abcd,func) __cpuid((int*)abcd,func)
|
# define EIGEN_CPUID(abcd,func) __cpuid((int*)abcd,func)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
inline bool ei_cpuid_is_vendor(int abcd[4], const char* vendor)
|
||||||
|
{
|
||||||
|
return abcd[1]==((int*)(vendor))[0] && abcd[3]==((int*)(vendor))[1] && abcd[2]==((int*)(vendor))[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void ei_queryCacheSizes_intel(int& l1, int& l2, int& l3)
|
||||||
|
{
|
||||||
|
int abcd[4];
|
||||||
|
l1 = l2 = l3 = 0;
|
||||||
|
int cache_id = 0;
|
||||||
|
int cache_type = 0;
|
||||||
|
do {
|
||||||
|
EIGEN_CPUID(abcd,0x4,cache_id);
|
||||||
|
cache_type = (abcd[0] & 0x0F) >> 0;
|
||||||
|
if(cache_type==1||cache_type==3) // data or unified cache
|
||||||
|
{
|
||||||
|
int cache_level = (abcd[0] & 0xE0) >> 5; // A[7:5]
|
||||||
|
int ways = (abcd[1] & 0xFFC00000) >> 22; // B[31:22]
|
||||||
|
int partitions = (abcd[1] & 0x003FF000) >> 12; // B[21:12]
|
||||||
|
int line_size = (abcd[1] & 0x00000FFF) >> 0; // B[11:0]
|
||||||
|
int sets = (abcd[2]); // C[31:0]
|
||||||
|
|
||||||
|
int cache_size = (ways+1) * (partitions+1) * (line_size+1) * (sets+1);
|
||||||
|
|
||||||
|
switch(cache_level)
|
||||||
|
{
|
||||||
|
case 1: l1 = cache_size; break;
|
||||||
|
case 2: l2 = cache_size; break;
|
||||||
|
case 3: l3 = cache_size; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cache_id++;
|
||||||
|
} while(cache_type>0);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void ei_queryCacheSizes_amd(int& l1, int& l2, int& l3)
|
||||||
|
{
|
||||||
|
int abcd[4];
|
||||||
|
EIGEN_CPUID(abcd,0x80000005,0);
|
||||||
|
l1 = (abcd[2] >> 24) * 1024; // C[31:24] = L1 size in KB
|
||||||
|
EIGEN_CPUID(abcd,0x80000006,0);
|
||||||
|
l2 = (abcd[2] >> 16) * 1024; // C[31;16] = l2 cache size in KB
|
||||||
|
l3 = ((abcd[3] & 0xFFFC000) >> 18) * 512 * 1024; // D[31;18] = l3 cache size in 512KB
|
||||||
|
}
|
||||||
|
|
||||||
/** \internal
|
/** \internal
|
||||||
* Queries and returns the cache sizes in Bytes of the L1, L2, and L3 data caches respectively */
|
* Queries and returns the cache sizes in Bytes of the L1, L2, and L3 data caches respectively */
|
||||||
inline void ei_queryCacheSizes(int& l1, int& l2, int& l3)
|
inline void ei_queryCacheSizes(int& l1, int& l2, int& l3)
|
||||||
@ -606,54 +652,30 @@ inline void ei_queryCacheSizes(int& l1, int& l2, int& l3)
|
|||||||
#ifdef EIGEN_CPUID
|
#ifdef EIGEN_CPUID
|
||||||
int abcd[4];
|
int abcd[4];
|
||||||
|
|
||||||
const char GenuineIntel_char[] = "GenuntelineI";
|
// identify the CPU vendor
|
||||||
const int* GenuineIntel = (int*)GenuineIntel_char;
|
|
||||||
|
|
||||||
const char AuthenticAMD_char[] = "AuthcAMDenti";
|
|
||||||
const int* AuthenticAMD = (int*)AuthenticAMD_char;
|
|
||||||
|
|
||||||
// Step 1: identify the CPU model
|
|
||||||
EIGEN_CPUID(abcd,0x0,0);
|
EIGEN_CPUID(abcd,0x0,0);
|
||||||
if(abcd[1]==GenuineIntel[0] && abcd[2]==GenuineIntel[1] && abcd[3]==GenuineIntel[2])
|
//if(abcd[1]==GenuineIntel[0] && abcd[2]==GenuineIntel[1] && abcd[3]==GenuineIntel[2])
|
||||||
{
|
if(ei_cpuid_is_vendor(abcd,"GenuineIntel"))
|
||||||
// use Intel's cpuid API
|
ei_queryCacheSizes_intel(l1,l2,l3);
|
||||||
l1 = l2 = l3 = 0;
|
else if(ei_cpuid_is_vendor(abcd,"AuthenticAMD") || ei_cpuid_is_vendor(abcd,"AMDisbetter!"))
|
||||||
int cache_id = 0;
|
ei_queryCacheSizes_amd(l1,l2,l3);
|
||||||
int cache_type = 0;
|
else
|
||||||
do {
|
// by default let's use Intel's API
|
||||||
EIGEN_CPUID(abcd,0x4,cache_id);
|
ei_queryCacheSizes_intel(l1,l2,l3);
|
||||||
cache_type = (abcd[0] & 0x0F) >> 0;
|
|
||||||
if(cache_type==1||cache_type==3) // data or unified cache
|
// here is the list of other vendors:
|
||||||
{
|
// ||ei_cpuid_is_vendor(abcd,"VIA VIA VIA ")
|
||||||
int cache_level = (abcd[0] & 0xE0) >> 5; // A[7:5]
|
// ||ei_cpuid_is_vendor(abcd,"CyrixInstead")
|
||||||
int ways = (abcd[1] & 0xFFC00000) >> 22; // B[31:22]
|
// ||ei_cpuid_is_vendor(abcd,"CentaurHauls")
|
||||||
int partitions = (abcd[1] & 0x003FF000) >> 12; // B[21:12]
|
// ||ei_cpuid_is_vendor(abcd,"GenuineTMx86")
|
||||||
int line_size = (abcd[1] & 0x00000FFF) >> 0; // B[11:0]
|
// ||ei_cpuid_is_vendor(abcd,"TransmetaCPU")
|
||||||
int sets = (abcd[2]); // C[31:0]
|
// ||ei_cpuid_is_vendor(abcd,"RiseRiseRise")
|
||||||
|
// ||ei_cpuid_is_vendor(abcd,"Geode by NSC")
|
||||||
int cache_size = (ways+1) * (partitions+1) * (line_size+1) * (sets+1);
|
// ||ei_cpuid_is_vendor(abcd,"SiS SiS SiS ")
|
||||||
|
// ||ei_cpuid_is_vendor(abcd,"UMC UMC UMC ")
|
||||||
switch(cache_level)
|
// ||ei_cpuid_is_vendor(abcd,"NexGenDriven")
|
||||||
{
|
// ||ei_cpuid_is_vendor(abcd,"CentaurHauls")
|
||||||
case 1: l1 = cache_size; break;
|
// ||ei_cpuid_is_vendor(abcd,"CentaurHauls")
|
||||||
case 2: l2 = cache_size; break;
|
|
||||||
case 3: l3 = cache_size; break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cache_id++;
|
|
||||||
} while(cache_type>0);
|
|
||||||
}
|
|
||||||
else if(abcd[1]==AuthenticAMD[0] && abcd[2]==AuthenticAMD[1] && abcd[3]==AuthenticAMD[2])
|
|
||||||
{
|
|
||||||
// use AMD's cpuid API
|
|
||||||
EIGEN_CPUID(abcd,0x80000005,0);
|
|
||||||
l1 = (abcd[2] >> 24) * 1024; // C[31:24] = L1 size in KB
|
|
||||||
EIGEN_CPUID(abcd,0x80000006,0);
|
|
||||||
l2 = (abcd[2] >> 16) * 1024; // C[31;16] = l2 cache size in KB
|
|
||||||
l3 = ((abcd[3] & 0xFFFC000) >> 18) * 512 * 1024; // D[31;18] = l3 cache size in 512KB
|
|
||||||
}
|
|
||||||
// TODO support other vendors
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user