cpu.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. //go:build darwin && arm64 && cgo
  2. package m1cpu
  3. // #cgo LDFLAGS: -framework CoreFoundation -framework IOKit
  4. // #include <AvailabilityMacros.h>
  5. // #include <CoreFoundation/CoreFoundation.h>
  6. // #include <IOKit/IOKitLib.h>
  7. // #include <sys/sysctl.h>
  8. //
  9. // #if !defined(MAC_OS_VERSION_12_0) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_VERSION_12_0
  10. // #define kIOMainPortDefault kIOMasterPortDefault
  11. // #endif
  12. //
  13. // #define HzToGHz(hz) ((hz) / 1000000000.0)
  14. //
  15. // UInt64 global_pCoreHz;
  16. // UInt64 global_eCoreHz;
  17. // int global_pCoreCount;
  18. // int global_eCoreCount;
  19. // int global_pCoreL1InstCacheSize;
  20. // int global_eCoreL1InstCacheSize;
  21. // int global_pCoreL1DataCacheSize;
  22. // int global_eCoreL1DataCacheSize;
  23. // int global_pCoreL2CacheSize;
  24. // int global_eCoreL2CacheSize;
  25. // char global_brand[32];
  26. //
  27. // UInt64 getFrequency(CFTypeRef typeRef) {
  28. // CFDataRef cfData = typeRef;
  29. //
  30. // CFIndex size = CFDataGetLength(cfData);
  31. // UInt8 buf[size];
  32. // CFDataGetBytes(cfData, CFRangeMake(0, size), buf);
  33. //
  34. // UInt8 b1 = buf[size-5];
  35. // UInt8 b2 = buf[size-6];
  36. // UInt8 b3 = buf[size-7];
  37. // UInt8 b4 = buf[size-8];
  38. //
  39. // UInt64 pCoreHz = 0x00000000FFFFFFFF & ((b1<<24) | (b2 << 16) | (b3 << 8) | (b4));
  40. // return pCoreHz;
  41. // }
  42. //
  43. // int sysctl_int(const char * name) {
  44. // int value = -1;
  45. // size_t size = 8;
  46. // sysctlbyname(name, &value, &size, NULL, 0);
  47. // return value;
  48. // }
  49. //
  50. // void sysctl_string(const char * name, char * dest) {
  51. // size_t size = 32;
  52. // sysctlbyname(name, dest, &size, NULL, 0);
  53. // }
  54. //
  55. // void initialize() {
  56. // global_pCoreCount = sysctl_int("hw.perflevel0.physicalcpu");
  57. // global_eCoreCount = sysctl_int("hw.perflevel1.physicalcpu");
  58. // global_pCoreL1InstCacheSize = sysctl_int("hw.perflevel0.l1icachesize");
  59. // global_eCoreL1InstCacheSize = sysctl_int("hw.perflevel1.l1icachesize");
  60. // global_pCoreL1DataCacheSize = sysctl_int("hw.perflevel0.l1dcachesize");
  61. // global_eCoreL1DataCacheSize = sysctl_int("hw.perflevel1.l1dcachesize");
  62. // global_pCoreL2CacheSize = sysctl_int("hw.perflevel0.l2cachesize");
  63. // global_eCoreL2CacheSize = sysctl_int("hw.perflevel1.l2cachesize");
  64. // sysctl_string("machdep.cpu.brand_string", global_brand);
  65. //
  66. // CFMutableDictionaryRef matching = IOServiceMatching("AppleARMIODevice");
  67. // io_iterator_t iter;
  68. // IOServiceGetMatchingServices(kIOMainPortDefault, matching, &iter);
  69. //
  70. // const size_t bufsize = 512;
  71. // io_object_t obj;
  72. // while ((obj = IOIteratorNext(iter))) {
  73. // char class[bufsize];
  74. // IOObjectGetClass(obj, class);
  75. // char name[bufsize];
  76. // IORegistryEntryGetName(obj, name);
  77. //
  78. // if (strncmp(name, "pmgr", bufsize) == 0) {
  79. // CFTypeRef pCoreRef = IORegistryEntryCreateCFProperty(obj, CFSTR("voltage-states5-sram"), kCFAllocatorDefault, 0);
  80. // CFTypeRef eCoreRef = IORegistryEntryCreateCFProperty(obj, CFSTR("voltage-states1-sram"), kCFAllocatorDefault, 0);
  81. //
  82. // long long pCoreHz = getFrequency(pCoreRef);
  83. // long long eCoreHz = getFrequency(eCoreRef);
  84. //
  85. // global_pCoreHz = pCoreHz;
  86. // global_eCoreHz = eCoreHz;
  87. // return;
  88. // }
  89. // }
  90. // }
  91. //
  92. // UInt64 eCoreHz() {
  93. // return global_eCoreHz;
  94. // }
  95. //
  96. // UInt64 pCoreHz() {
  97. // return global_pCoreHz;
  98. // }
  99. //
  100. // Float64 eCoreGHz() {
  101. // return HzToGHz(global_eCoreHz);
  102. // }
  103. //
  104. // Float64 pCoreGHz() {
  105. // return HzToGHz(global_pCoreHz);
  106. // }
  107. //
  108. // int pCoreCount() {
  109. // return global_pCoreCount;
  110. // }
  111. //
  112. // int eCoreCount() {
  113. // return global_eCoreCount;
  114. // }
  115. //
  116. // int pCoreL1InstCacheSize() {
  117. // return global_pCoreL1InstCacheSize;
  118. // }
  119. //
  120. // int pCoreL1DataCacheSize() {
  121. // return global_pCoreL1DataCacheSize;
  122. // }
  123. //
  124. // int pCoreL2CacheSize() {
  125. // return global_pCoreL2CacheSize;
  126. // }
  127. //
  128. // int eCoreL1InstCacheSize() {
  129. // return global_eCoreL1InstCacheSize;
  130. // }
  131. //
  132. // int eCoreL1DataCacheSize() {
  133. // return global_eCoreL1DataCacheSize;
  134. // }
  135. //
  136. // int eCoreL2CacheSize() {
  137. // return global_eCoreL2CacheSize;
  138. // }
  139. //
  140. // char * modelName() {
  141. // return global_brand;
  142. // }
  143. import "C"
  144. func init() {
  145. C.initialize()
  146. }
  147. // IsAppleSilicon returns true on this platform.
  148. func IsAppleSilicon() bool {
  149. return true
  150. }
  151. // PCoreHZ returns the max frequency in Hertz of the P-Core of an Apple Silicon CPU.
  152. func PCoreHz() uint64 {
  153. return uint64(C.pCoreHz())
  154. }
  155. // ECoreHZ returns the max frequency in Hertz of the E-Core of an Apple Silicon CPU.
  156. func ECoreHz() uint64 {
  157. return uint64(C.eCoreHz())
  158. }
  159. // PCoreGHz returns the max frequency in Gigahertz of the P-Core of an Apple Silicon CPU.
  160. func PCoreGHz() float64 {
  161. return float64(C.pCoreGHz())
  162. }
  163. // ECoreGHz returns the max frequency in Gigahertz of the E-Core of an Apple Silicon CPU.
  164. func ECoreGHz() float64 {
  165. return float64(C.eCoreGHz())
  166. }
  167. // PCoreCount returns the number of physical P (performance) cores.
  168. func PCoreCount() int {
  169. return int(C.pCoreCount())
  170. }
  171. // ECoreCount returns the number of physical E (efficiency) cores.
  172. func ECoreCount() int {
  173. return int(C.eCoreCount())
  174. }
  175. // PCoreCacheSize returns the sizes of the P (performance) core cache sizes
  176. // in the order of
  177. //
  178. // - L1 instruction cache
  179. // - L1 data cache
  180. // - L2 cache
  181. func PCoreCache() (int, int, int) {
  182. return int(C.pCoreL1InstCacheSize()),
  183. int(C.pCoreL1DataCacheSize()),
  184. int(C.pCoreL2CacheSize())
  185. }
  186. // ECoreCacheSize returns the sizes of the E (efficiency) core cache sizes
  187. // in the order of
  188. //
  189. // - L1 instruction cache
  190. // - L1 data cache
  191. // - L2 cache
  192. func ECoreCache() (int, int, int) {
  193. return int(C.eCoreL1InstCacheSize()),
  194. int(C.eCoreL1DataCacheSize()),
  195. int(C.eCoreL2CacheSize())
  196. }
  197. // ModelName returns the model name of the CPU.
  198. func ModelName() string {
  199. return C.GoString(C.modelName())
  200. }