Bug 16028 – Incorrect cache size returned from core.cpuid

Status
NEW
Severity
normal
Priority
P3
Component
druntime
Product
D
Version
D2
Platform
All
OS
All
Creation time
2016-05-15T19:51:41Z
Last change time
2024-12-07T13:36:32Z
Assigned to
No Owner
Creator
Walter Bright
Moved to GitHub: dmd#17328 →

Comments

Comment #0 by bugzilla — 2016-05-15T19:51:41Z
https://www.reddit.com/r/programming/comments/4jfoez/cache_sizes_with_cpuid_in_c_and_d/ http://blog.melkerlitsgard.se/2016/05/12/cache-sizes-with-cpuid/ Example code from the article: int getCacheSize(int cacheLevel) { // Intel stores it's cache information in eax4, with ecx as index // The information received is as following: // ebx[31:22] = Ways of associativity // ebx[21:12] = Physical line partitions // ebx[11: 0] = Line size asm { mov EAX, functionID; mov ECX, cacheLevl; // The index here is the cache level (0 = L1i, 1 = L1d, 2 = L2 etc.) cpuid; mov cpuInfo, EAX; mov cpuInfo + 4, EBX; mov cpuInfo + 8, ECX; mov cpuInfo + 12, EDX; } int ways = cpuInfo[1] & 0xffc00000; // This receives bit 22 to 31 from the ebx register ways >>= 22; // Bitshift it 22 bits to get the real value, since we started reading from bit 22 int partitions = cpuInfo[1] & 0x7fe00; // This receives bit 12 to 22 partitions >>= 12; // Same here, bitshift 12 bits int lineSize = cpuInfo[1] & 0x7ff; // This receives bit 0 to 11 int sets = cpuInfo[2]; // The sets are the value of the ecx register // All of these values needs one appended to them to get the real value return (ways + 1) * (partitions + 1) * (lineSize + 1) * (sets + 1); }
Comment #1 by ilyayaroshenko — 2016-07-08T14:04:53Z
This is compiles: /++ Returns: cache size in KBs. Params: cacheLevel = cache level (0 = L1d, 1 = L1i, 2 = L2 etc.) +/ int getCacheSize(int cacheLevel) { enum functionID = 0x04; // Intel stores it's cache information in eax4, with ecx as index // The information received is as following: // ebx[31:22] = Ways of associativity // ebx[21:12] = Physical line partitions // ebx[11: 0] = Line size int[4] cpuInfo; asm { mov EAX, functionID; mov ECX, cacheLevel; cpuid; mov cpuInfo + 0x0, EAX; mov cpuInfo + 0x4, EBX; mov cpuInfo + 0x8, ECX; mov cpuInfo + 0xC, EDX; } int ways = cpuInfo[1] & 0xffc00000; // This receives bit 22 to 31 from the ebx register ways >>= 22; // Bitshift it 22 bits to get the real value, since we started reading from bit 22 int partitions = cpuInfo[1] & 0x3ff800; // This receives bit 12 to 21 partitions >>= 12; // Same here, bitshift 12 bits int lineSize = cpuInfo[1] & 0x7ff; // This receives bit 0 to 11 int sets = cpuInfo[2]; // The sets are the value of the ecx register // All of these values needs one appended to them to get the real value int ret = (ways + 1) * (partitions + 1) * (lineSize + 1) * (sets + 1); assert(ret % 1024 == 0); return ret >> 10; }
Comment #2 by ilyayaroshenko — 2016-07-09T17:43:35Z
Replacement for core.cpuid: https://github.com/libmir/cpuid
Comment #3 by robert.schadek — 2024-12-07T13:36:32Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/17328 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB