1// Copyright (c) 2015 Klaus Post, released under MIT License. See LICENSE file. 2 3package cpuid 4 5import ( 6 "fmt" 7 "testing" 8) 9 10// There is no real way to test a CPU identifier, since results will 11// obviously differ on each machine. 12func TestCPUID(t *testing.T) { 13 n := maxFunctionID() 14 t.Logf("Max Function:0x%x\n", n) 15 n = maxExtendedFunction() 16 t.Logf("Max Extended Function:0x%x\n", n) 17 t.Log("Name:", CPU.BrandName) 18 t.Log("PhysicalCores:", CPU.PhysicalCores) 19 t.Log("ThreadsPerCore:", CPU.ThreadsPerCore) 20 t.Log("LogicalCores:", CPU.LogicalCores) 21 t.Log("Family", CPU.Family, "Model:", CPU.Model) 22 t.Log("Features:", CPU.Features) 23 t.Log("Cacheline bytes:", CPU.CacheLine) 24 t.Log("L1 Instruction Cache:", CPU.Cache.L1I, "bytes") 25 t.Log("L1 Data Cache:", CPU.Cache.L1D, "bytes") 26 t.Log("L2 Cache:", CPU.Cache.L2, "bytes") 27 t.Log("L3 Cache:", CPU.Cache.L3, "bytes") 28 29 if CPU.SSE2() { 30 t.Log("We have SSE2") 31 } 32} 33 34func TestDumpCPUID(t *testing.T) { 35 n := int(maxFunctionID()) 36 for i := 0; i <= n; i++ { 37 a, b, c, d := cpuidex(uint32(i), 0) 38 t.Logf("CPUID %08x: %08x-%08x-%08x-%08x", i, a, b, c, d) 39 ex := uint32(1) 40 for { 41 a2, b2, c2, d2 := cpuidex(uint32(i), ex) 42 if a2 == a && b2 == b && d2 == d || ex > 50 || a2 == 0 { 43 break 44 } 45 t.Logf("CPUID %08x: %08x-%08x-%08x-%08x", i, a2, b2, c2, d2) 46 a, b, c, d = a2, b2, c2, d2 47 ex++ 48 } 49 } 50 n2 := maxExtendedFunction() 51 for i := uint32(0x80000000); i <= n2; i++ { 52 a, b, c, d := cpuid(i) 53 t.Logf("CPUID %08x: %08x-%08x-%08x-%08x", i, a, b, c, d) 54 } 55} 56 57func Example() { 58 // Print basic CPU information: 59 fmt.Println("Name:", CPU.BrandName) 60 fmt.Println("PhysicalCores:", CPU.PhysicalCores) 61 fmt.Println("ThreadsPerCore:", CPU.ThreadsPerCore) 62 fmt.Println("LogicalCores:", CPU.LogicalCores) 63 fmt.Println("Family", CPU.Family, "Model:", CPU.Model) 64 fmt.Println("Features:", CPU.Features) 65 fmt.Println("Cacheline bytes:", CPU.CacheLine) 66 67 // Test if we have a specific feature: 68 if CPU.SSE() { 69 fmt.Println("We have Streaming SIMD Extensions") 70 } 71} 72 73func TestBrandNameZero(t *testing.T) { 74 if len(CPU.BrandName) > 0 { 75 // Cut out last byte 76 last := []byte(CPU.BrandName[len(CPU.BrandName)-1:]) 77 if last[0] == 0 { 78 t.Fatal("last byte was zero") 79 } else if last[0] == 32 { 80 t.Fatal("whitespace wasn't trimmed") 81 } 82 } 83} 84 85// Generated here: http://play.golang.org/p/mko-0tFt0Q 86 87// TestCmov tests Cmov() function 88func TestCmov(t *testing.T) { 89 got := CPU.Cmov() 90 expected := CPU.Features&CMOV == CMOV 91 if got != expected { 92 t.Fatalf("Cmov: expected %v, got %v", expected, got) 93 } 94 t.Log("CMOV Support:", got) 95} 96 97// TestAmd3dnow tests Amd3dnow() function 98func TestAmd3dnow(t *testing.T) { 99 got := CPU.Amd3dnow() 100 expected := CPU.Features&AMD3DNOW == AMD3DNOW 101 if got != expected { 102 t.Fatalf("Amd3dnow: expected %v, got %v", expected, got) 103 } 104 t.Log("AMD3DNOW Support:", got) 105} 106 107// TestAmd3dnowExt tests Amd3dnowExt() function 108func TestAmd3dnowExt(t *testing.T) { 109 got := CPU.Amd3dnowExt() 110 expected := CPU.Features&AMD3DNOWEXT == AMD3DNOWEXT 111 if got != expected { 112 t.Fatalf("Amd3dnowExt: expected %v, got %v", expected, got) 113 } 114 t.Log("AMD3DNOWEXT Support:", got) 115} 116 117// TestVMX tests VMX() function 118func TestVMX(t *testing.T) { 119 got := CPU.VMX() 120 expected := CPU.Features&VMX == VMX 121 if got != expected { 122 t.Fatalf("VMX: expected %v, got %v", expected, got) 123 } 124 t.Log("VMX Support:", got) 125} 126 127// TestMMX tests MMX() function 128func TestMMX(t *testing.T) { 129 got := CPU.MMX() 130 expected := CPU.Features&MMX == MMX 131 if got != expected { 132 t.Fatalf("MMX: expected %v, got %v", expected, got) 133 } 134 t.Log("MMX Support:", got) 135} 136 137// TestMMXext tests MMXext() function 138func TestMMXext(t *testing.T) { 139 got := CPU.MMXExt() 140 expected := CPU.Features&MMXEXT == MMXEXT 141 if got != expected { 142 t.Fatalf("MMXExt: expected %v, got %v", expected, got) 143 } 144 t.Log("MMXEXT Support:", got) 145} 146 147// TestSSE tests SSE() function 148func TestSSE(t *testing.T) { 149 got := CPU.SSE() 150 expected := CPU.Features&SSE == SSE 151 if got != expected { 152 t.Fatalf("SSE: expected %v, got %v", expected, got) 153 } 154 t.Log("SSE Support:", got) 155} 156 157// TestSSE2 tests SSE2() function 158func TestSSE2(t *testing.T) { 159 got := CPU.SSE2() 160 expected := CPU.Features&SSE2 == SSE2 161 if got != expected { 162 t.Fatalf("SSE2: expected %v, got %v", expected, got) 163 } 164 t.Log("SSE2 Support:", got) 165} 166 167// TestSSE3 tests SSE3() function 168func TestSSE3(t *testing.T) { 169 got := CPU.SSE3() 170 expected := CPU.Features&SSE3 == SSE3 171 if got != expected { 172 t.Fatalf("SSE3: expected %v, got %v", expected, got) 173 } 174 t.Log("SSE3 Support:", got) 175} 176 177// TestSSSE3 tests SSSE3() function 178func TestSSSE3(t *testing.T) { 179 got := CPU.SSSE3() 180 expected := CPU.Features&SSSE3 == SSSE3 181 if got != expected { 182 t.Fatalf("SSSE3: expected %v, got %v", expected, got) 183 } 184 t.Log("SSSE3 Support:", got) 185} 186 187// TestSSE4 tests SSE4() function 188func TestSSE4(t *testing.T) { 189 got := CPU.SSE4() 190 expected := CPU.Features&SSE4 == SSE4 191 if got != expected { 192 t.Fatalf("SSE4: expected %v, got %v", expected, got) 193 } 194 t.Log("SSE4 Support:", got) 195} 196 197// TestSSE42 tests SSE42() function 198func TestSSE42(t *testing.T) { 199 got := CPU.SSE42() 200 expected := CPU.Features&SSE42 == SSE42 201 if got != expected { 202 t.Fatalf("SSE42: expected %v, got %v", expected, got) 203 } 204 t.Log("SSE42 Support:", got) 205} 206 207// TestAVX tests AVX() function 208func TestAVX(t *testing.T) { 209 got := CPU.AVX() 210 expected := CPU.Features&AVX == AVX 211 if got != expected { 212 t.Fatalf("AVX: expected %v, got %v", expected, got) 213 } 214 t.Log("AVX Support:", got) 215} 216 217// TestAVX2 tests AVX2() function 218func TestAVX2(t *testing.T) { 219 got := CPU.AVX2() 220 expected := CPU.Features&AVX2 == AVX2 221 if got != expected { 222 t.Fatalf("AVX2: expected %v, got %v", expected, got) 223 } 224 t.Log("AVX2 Support:", got) 225} 226 227// TestFMA3 tests FMA3() function 228func TestFMA3(t *testing.T) { 229 got := CPU.FMA3() 230 expected := CPU.Features&FMA3 == FMA3 231 if got != expected { 232 t.Fatalf("FMA3: expected %v, got %v", expected, got) 233 } 234 t.Log("FMA3 Support:", got) 235} 236 237// TestFMA4 tests FMA4() function 238func TestFMA4(t *testing.T) { 239 got := CPU.FMA4() 240 expected := CPU.Features&FMA4 == FMA4 241 if got != expected { 242 t.Fatalf("FMA4: expected %v, got %v", expected, got) 243 } 244 t.Log("FMA4 Support:", got) 245} 246 247// TestXOP tests XOP() function 248func TestXOP(t *testing.T) { 249 got := CPU.XOP() 250 expected := CPU.Features&XOP == XOP 251 if got != expected { 252 t.Fatalf("XOP: expected %v, got %v", expected, got) 253 } 254 t.Log("XOP Support:", got) 255} 256 257// TestF16C tests F16C() function 258func TestF16C(t *testing.T) { 259 got := CPU.F16C() 260 expected := CPU.Features&F16C == F16C 261 if got != expected { 262 t.Fatalf("F16C: expected %v, got %v", expected, got) 263 } 264 t.Log("F16C Support:", got) 265} 266 267// TestCX16 tests CX16() function 268func TestCX16(t *testing.T) { 269 got := CPU.CX16() 270 expected := CPU.Features&CX16 == CX16 271 if got != expected { 272 t.Fatalf("CX16: expected %v, got %v", expected, got) 273 } 274 t.Log("CX16 Support:", got) 275} 276 277// TestSGX tests SGX detection 278func TestSGX(t *testing.T) { 279 got := CPU.SGX.Available 280 expected := CPU.Features&SGX == SGX 281 if got != expected { 282 t.Fatalf("SGX: expected %v, got %v", expected, got) 283 } 284 t.Log("SGX Support:", got) 285 286 if CPU.SGX.Available { 287 var total uint64 = 0 288 leaves := false 289 for _, s := range CPU.SGX.EPCSections { 290 t.Logf("SGX EPC section: base address 0x%x, size %v", s.BaseAddress, s.EPCSize) 291 total += s.EPCSize 292 leaves = true 293 } 294 if leaves && total == 0 { 295 t.Fatal("SGX enabled without any available EPC memory") 296 } 297 } 298} 299 300// TestSGXLC tests SGX Launch Control detection 301func TestSGXLC(t *testing.T) { 302 got := CPU.SGX.LaunchControl 303 expected := CPU.Features&SGXLC == SGXLC 304 if got != expected { 305 t.Fatalf("SGX: expected %v, got %v", expected, got) 306 } 307 t.Log("SGX Launch Control Support:", got) 308} 309 310// TestBMI1 tests BMI1() function 311func TestBMI1(t *testing.T) { 312 got := CPU.BMI1() 313 expected := CPU.Features&BMI1 == BMI1 314 if got != expected { 315 t.Fatalf("BMI1: expected %v, got %v", expected, got) 316 } 317 t.Log("BMI1 Support:", got) 318} 319 320// TestBMI2 tests BMI2() function 321func TestBMI2(t *testing.T) { 322 got := CPU.BMI2() 323 expected := CPU.Features&BMI2 == BMI2 324 if got != expected { 325 t.Fatalf("BMI2: expected %v, got %v", expected, got) 326 } 327 t.Log("BMI2 Support:", got) 328} 329 330// TestTBM tests TBM() function 331func TestTBM(t *testing.T) { 332 got := CPU.TBM() 333 expected := CPU.Features&TBM == TBM 334 if got != expected { 335 t.Fatalf("TBM: expected %v, got %v", expected, got) 336 } 337 t.Log("TBM Support:", got) 338} 339 340// TestLzcnt tests Lzcnt() function 341func TestLzcnt(t *testing.T) { 342 got := CPU.Lzcnt() 343 expected := CPU.Features&LZCNT == LZCNT 344 if got != expected { 345 t.Fatalf("Lzcnt: expected %v, got %v", expected, got) 346 } 347 t.Log("LZCNT Support:", got) 348} 349 350// TestLzcnt tests Lzcnt() function 351func TestPopcnt(t *testing.T) { 352 got := CPU.Popcnt() 353 expected := CPU.Features&POPCNT == POPCNT 354 if got != expected { 355 t.Fatalf("Popcnt: expected %v, got %v", expected, got) 356 } 357 t.Log("POPCNT Support:", got) 358} 359 360// TestAesNi tests AesNi() function 361func TestAesNi(t *testing.T) { 362 got := CPU.AesNi() 363 expected := CPU.Features&AESNI == AESNI 364 if got != expected { 365 t.Fatalf("AesNi: expected %v, got %v", expected, got) 366 } 367 t.Log("AESNI Support:", got) 368} 369 370// TestHTT tests HTT() function 371func TestHTT(t *testing.T) { 372 got := CPU.HTT() 373 expected := CPU.Features&HTT == HTT 374 if got != expected { 375 t.Fatalf("HTT: expected %v, got %v", expected, got) 376 } 377 t.Log("HTT Support:", got) 378} 379 380// TestClmul tests Clmul() function 381func TestClmul(t *testing.T) { 382 got := CPU.Clmul() 383 expected := CPU.Features&CLMUL == CLMUL 384 if got != expected { 385 t.Fatalf("Clmul: expected %v, got %v", expected, got) 386 } 387 t.Log("CLMUL Support:", got) 388} 389 390// TestSSE2Slow tests SSE2Slow() function 391func TestSSE2Slow(t *testing.T) { 392 got := CPU.SSE2Slow() 393 expected := CPU.Features&SSE2SLOW == SSE2SLOW 394 if got != expected { 395 t.Fatalf("SSE2Slow: expected %v, got %v", expected, got) 396 } 397 t.Log("SSE2SLOW Support:", got) 398} 399 400// TestSSE3Slow tests SSE3slow() function 401func TestSSE3Slow(t *testing.T) { 402 got := CPU.SSE3Slow() 403 expected := CPU.Features&SSE3SLOW == SSE3SLOW 404 if got != expected { 405 t.Fatalf("SSE3slow: expected %v, got %v", expected, got) 406 } 407 t.Log("SSE3SLOW Support:", got) 408} 409 410// TestAtom tests Atom() function 411func TestAtom(t *testing.T) { 412 got := CPU.Atom() 413 expected := CPU.Features&ATOM == ATOM 414 if got != expected { 415 t.Fatalf("Atom: expected %v, got %v", expected, got) 416 } 417 t.Log("ATOM Support:", got) 418} 419 420// TestNX tests NX() function (NX (No-Execute) bit) 421func TestNX(t *testing.T) { 422 got := CPU.NX() 423 expected := CPU.Features&NX == NX 424 if got != expected { 425 t.Fatalf("NX: expected %v, got %v", expected, got) 426 } 427 t.Log("NX Support:", got) 428} 429 430// TestSSE4A tests SSE4A() function (AMD Barcelona microarchitecture SSE4a instructions) 431func TestSSE4A(t *testing.T) { 432 got := CPU.SSE4A() 433 expected := CPU.Features&SSE4A == SSE4A 434 if got != expected { 435 t.Fatalf("SSE4A: expected %v, got %v", expected, got) 436 } 437 t.Log("SSE4A Support:", got) 438} 439 440// TestHLE tests HLE() function (Hardware Lock Elision) 441func TestHLE(t *testing.T) { 442 got := CPU.HLE() 443 expected := CPU.Features&HLE == HLE 444 if got != expected { 445 t.Fatalf("HLE: expected %v, got %v", expected, got) 446 } 447 t.Log("HLE Support:", got) 448} 449 450// TestRTM tests RTM() function (Restricted Transactional Memory) 451func TestRTM(t *testing.T) { 452 got := CPU.RTM() 453 expected := CPU.Features&RTM == RTM 454 if got != expected { 455 t.Fatalf("RTM: expected %v, got %v", expected, got) 456 } 457 t.Log("RTM Support:", got) 458} 459 460// TestRdrand tests RDRAND() function (RDRAND instruction is available) 461func TestRdrand(t *testing.T) { 462 got := CPU.Rdrand() 463 expected := CPU.Features&RDRAND == RDRAND 464 if got != expected { 465 t.Fatalf("Rdrand: expected %v, got %v", expected, got) 466 } 467 t.Log("Rdrand Support:", got) 468} 469 470// TestRdseed tests RDSEED() function (RDSEED instruction is available) 471func TestRdseed(t *testing.T) { 472 got := CPU.Rdseed() 473 expected := CPU.Features&RDSEED == RDSEED 474 if got != expected { 475 t.Fatalf("Rdseed: expected %v, got %v", expected, got) 476 } 477 t.Log("Rdseed Support:", got) 478} 479 480// TestADX tests ADX() function (Intel ADX (Multi-Precision Add-Carry Instruction Extensions)) 481func TestADX(t *testing.T) { 482 got := CPU.ADX() 483 expected := CPU.Features&ADX == ADX 484 if got != expected { 485 t.Fatalf("ADX: expected %v, got %v", expected, got) 486 } 487 t.Log("ADX Support:", got) 488} 489 490// TestSHA tests SHA() function (Intel SHA Extensions) 491func TestSHA(t *testing.T) { 492 got := CPU.SHA() 493 expected := CPU.Features&SHA == SHA 494 if got != expected { 495 t.Fatalf("SHA: expected %v, got %v", expected, got) 496 } 497 t.Log("SHA Support:", got) 498} 499 500// TestAVX512F tests AVX512F() function (AVX-512 Foundation) 501func TestAVX512F(t *testing.T) { 502 got := CPU.AVX512F() 503 expected := CPU.Features&AVX512F == AVX512F 504 if got != expected { 505 t.Fatalf("AVX512F: expected %v, got %v", expected, got) 506 } 507 t.Log("AVX512F Support:", got) 508} 509 510// TestAVX512DQ tests AVX512DQ() function (AVX-512 Doubleword and Quadword Instructions) 511func TestAVX512DQ(t *testing.T) { 512 got := CPU.AVX512DQ() 513 expected := CPU.Features&AVX512DQ == AVX512DQ 514 if got != expected { 515 t.Fatalf("AVX512DQ: expected %v, got %v", expected, got) 516 } 517 t.Log("AVX512DQ Support:", got) 518} 519 520// TestAVX512IFMA tests AVX512IFMA() function (AVX-512 Integer Fused Multiply-Add Instructions) 521func TestAVX512IFMA(t *testing.T) { 522 got := CPU.AVX512IFMA() 523 expected := CPU.Features&AVX512IFMA == AVX512IFMA 524 if got != expected { 525 t.Fatalf("AVX512IFMA: expected %v, got %v", expected, got) 526 } 527 t.Log("AVX512IFMA Support:", got) 528} 529 530// TestAVX512PF tests AVX512PF() function (AVX-512 Prefetch Instructions) 531func TestAVX512PF(t *testing.T) { 532 got := CPU.AVX512PF() 533 expected := CPU.Features&AVX512PF == AVX512PF 534 if got != expected { 535 t.Fatalf("AVX512PF: expected %v, got %v", expected, got) 536 } 537 t.Log("AVX512PF Support:", got) 538} 539 540// TestAVX512ER tests AVX512ER() function (AVX-512 Exponential and Reciprocal Instructions) 541func TestAVX512ER(t *testing.T) { 542 got := CPU.AVX512ER() 543 expected := CPU.Features&AVX512ER == AVX512ER 544 if got != expected { 545 t.Fatalf("AVX512ER: expected %v, got %v", expected, got) 546 } 547 t.Log("AVX512ER Support:", got) 548} 549 550// TestAVX512CD tests AVX512CD() function (AVX-512 Conflict Detection Instructions) 551func TestAVX512CD(t *testing.T) { 552 got := CPU.AVX512CD() 553 expected := CPU.Features&AVX512CD == AVX512CD 554 if got != expected { 555 t.Fatalf("AVX512CD: expected %v, got %v", expected, got) 556 } 557 t.Log("AVX512CD Support:", got) 558} 559 560// TestAVX512BW tests AVX512BW() function (AVX-512 Byte and Word Instructions) 561func TestAVX512BW(t *testing.T) { 562 got := CPU.AVX512BW() 563 expected := CPU.Features&AVX512BW == AVX512BW 564 if got != expected { 565 t.Fatalf("AVX512BW: expected %v, got %v", expected, got) 566 } 567 t.Log("AVX512BW Support:", got) 568} 569 570// TestAVX512VL tests AVX512VL() function (AVX-512 Vector Length Extensions) 571func TestAVX512VL(t *testing.T) { 572 got := CPU.AVX512VL() 573 expected := CPU.Features&AVX512VL == AVX512VL 574 if got != expected { 575 t.Fatalf("AVX512VL: expected %v, got %v", expected, got) 576 } 577 t.Log("AVX512VL Support:", got) 578} 579 580// TestAVX512VBMI tests AVX512VBMI() function (AVX-512 Vector Bit Manipulation Instructions) 581func TestAVX512VBMI(t *testing.T) { 582 got := CPU.AVX512VBMI() 583 expected := CPU.Features&AVX512VBMI == AVX512VBMI 584 if got != expected { 585 t.Fatalf("AVX512VBMI: expected %v, got %v", expected, got) 586 } 587 t.Log("AVX512VBMI Support:", got) 588} 589 590// TestAVX512_VBMI2 tests AVX512VBMI2 function (AVX-512 Vector Bit Manipulation Instructions, Version 2) 591func TestAVX512_VBMI2(t *testing.T) { 592 got := CPU.AVX512VBMI2() 593 expected := CPU.Features&AVX512VBMI2 == AVX512VBMI2 594 if got != expected { 595 t.Fatalf("AVX512VBMI2: expected %v, got %v", expected, got) 596 } 597 t.Log("AVX512VBMI2 Support:", got) 598} 599 600// TestAVX512_VNNI tests AVX512VNNI() function (AVX-512 Vector Neural Network Instructions) 601func TestAVX512_VNNI(t *testing.T) { 602 got := CPU.AVX512VNNI() 603 expected := CPU.Features&AVX512VNNI == AVX512VNNI 604 if got != expected { 605 t.Fatalf("AVX512VNNI: expected %v, got %v", expected, got) 606 } 607 t.Log("AVX512VNNI Support:", got) 608} 609 610// TestAVX512_VPOPCNTDQ tests AVX512VPOPCNTDQ() function (AVX-512 Vector Population Count Doubleword and Quadword) 611func TestAVX512_VPOPCNTDQ(t *testing.T) { 612 got := CPU.AVX512VPOPCNTDQ() 613 expected := CPU.Features&AVX512VPOPCNTDQ == AVX512VPOPCNTDQ 614 if got != expected { 615 t.Fatalf("AVX512VPOPCNTDQ: expected %v, got %v", expected, got) 616 } 617 t.Log("AVX512VPOPCNTDQ Support:", got) 618} 619 620// TestGFNI tests GFNI() function (Galois Field New Instructions) 621func TestGFNI(t *testing.T) { 622 got := CPU.GFNI() 623 expected := CPU.Features&GFNI == GFNI 624 if got != expected { 625 t.Fatalf("GFNI: expected %v, got %v", expected, got) 626 } 627 t.Log("GFNI Support:", got) 628} 629 630// TestVAES tests VAES() function (Vector AES) 631func TestVAES(t *testing.T) { 632 got := CPU.VAES() 633 expected := CPU.Features&VAES == VAES 634 if got != expected { 635 t.Fatalf("VAES: expected %v, got %v", expected, got) 636 } 637 t.Log("VAES Support:", got) 638} 639 640// TestAVX512_BITALG tests AVX512BITALG() function (AVX-512 Bit Algorithms) 641func TestAVX512_BITALG(t *testing.T) { 642 got := CPU.AVX512BITALG() 643 expected := CPU.Features&AVX512BITALG == AVX512BITALG 644 if got != expected { 645 t.Fatalf("AVX512BITALG: expected %v, got %v", expected, got) 646 } 647 t.Log("AVX512BITALG Support:", got) 648} 649 650// TestVPCLMULQDQ tests VPCLMULQDQ() function (Carry-Less Multiplication Quadword) 651func TestVPCLMULQDQ(t *testing.T) { 652 got := CPU.VPCLMULQDQ() 653 expected := CPU.Features&VPCLMULQDQ == VPCLMULQDQ 654 if got != expected { 655 t.Fatalf("VPCLMULQDQ: expected %v, got %v", expected, got) 656 } 657 t.Log("VPCLMULQDQ Support:", got) 658} 659 660// TestAVX512_BF16 tests AVX512BF16() function (AVX-512 BFLOAT16 Instructions) 661func TestAVX512_BF16(t *testing.T) { 662 got := CPU.AVX512BF16() 663 expected := CPU.Features&AVX512BF16 == AVX512BF16 664 if got != expected { 665 t.Fatalf("AVX512BF16: expected %v, got %v", expected, got) 666 } 667 t.Log("AVX512BF16 Support:", got) 668} 669 670// TestAVX512_VP2INTERSECT tests AVX512VP2INTERSECT() function (AVX-512 Intersect for D/Q) 671func TestAVX512_VP2INTERSECT(t *testing.T) { 672 got := CPU.AVX512VP2INTERSECT() 673 expected := CPU.Features&AVX512VP2INTERSECT == AVX512VP2INTERSECT 674 if got != expected { 675 t.Fatalf("AVX512VP2INTERSECT: expected %v, got %v", expected, got) 676 } 677 t.Log("AVX512VP2INTERSECT Support:", got) 678} 679 680// TestMPX tests MPX() function (Intel MPX (Memory Protection Extensions)) 681func TestMPX(t *testing.T) { 682 got := CPU.MPX() 683 expected := CPU.Features&MPX == MPX 684 if got != expected { 685 t.Fatalf("MPX: expected %v, got %v", expected, got) 686 } 687 t.Log("MPX Support:", got) 688} 689 690// TestERMS tests ERMS() function (Enhanced REP MOVSB/STOSB) 691func TestERMS(t *testing.T) { 692 got := CPU.ERMS() 693 expected := CPU.Features&ERMS == ERMS 694 if got != expected { 695 t.Fatalf("ERMS: expected %v, got %v", expected, got) 696 } 697 t.Log("ERMS Support:", got) 698} 699 700// TestVendor writes the detected vendor. Will be 0 if unknown 701func TestVendor(t *testing.T) { 702 t.Log("Vendor ID:", CPU.VendorID) 703} 704 705// Intel returns true if vendor is recognized as Intel 706func TestIntel(t *testing.T) { 707 got := CPU.Intel() 708 expected := CPU.VendorID == Intel 709 if got != expected { 710 t.Fatalf("TestIntel: expected %v, got %v", expected, got) 711 } 712 t.Log("TestIntel:", got) 713} 714 715// AMD returns true if vendor is recognized as AMD 716func TestAMD(t *testing.T) { 717 got := CPU.AMD() 718 expected := CPU.VendorID == AMD 719 if got != expected { 720 t.Fatalf("TestAMD: expected %v, got %v", expected, got) 721 } 722 t.Log("TestAMD:", got) 723} 724 725// Hygon returns true if vendor is recognized as Hygon 726func TestHygon(t *testing.T) { 727 got := CPU.Hygon() 728 expected := CPU.VendorID == Hygon 729 if got != expected { 730 t.Fatalf("TestHygon: expected %v, got %v", expected, got) 731 } 732 t.Log("TestHygon:", got) 733} 734 735// Transmeta returns true if vendor is recognized as Transmeta 736func TestTransmeta(t *testing.T) { 737 got := CPU.Transmeta() 738 expected := CPU.VendorID == Transmeta 739 if got != expected { 740 t.Fatalf("TestTransmeta: expected %v, got %v", expected, got) 741 } 742 t.Log("TestTransmeta:", got) 743} 744 745// NSC returns true if vendor is recognized as National Semiconductor 746func TestNSC(t *testing.T) { 747 got := CPU.NSC() 748 expected := CPU.VendorID == NSC 749 if got != expected { 750 t.Fatalf("TestNSC: expected %v, got %v", expected, got) 751 } 752 t.Log("TestNSC:", got) 753} 754 755// VIA returns true if vendor is recognized as VIA 756func TestVIA(t *testing.T) { 757 got := CPU.VIA() 758 expected := CPU.VendorID == VIA 759 if got != expected { 760 t.Fatalf("TestVIA: expected %v, got %v", expected, got) 761 } 762 t.Log("TestVIA:", got) 763} 764 765// Test VM function 766func TestVM(t *testing.T) { 767 t.Log("Vendor ID:", CPU.VM()) 768} 769 770// TSX returns true if cpu supports transactional sync extensions. 771func TestCPUInfo_TSX(t *testing.T) { 772 got := CPU.TSX() 773 expected := CPU.HLE() && CPU.RTM() 774 if got != expected { 775 t.Fatalf("TestCPUInfo_TSX: expected %v, got %v", expected, got) 776 } 777 t.Log("TestCPUInfo_TSX:", got) 778} 779 780// Test RTCounter function 781func TestRtCounter(t *testing.T) { 782 a := CPU.RTCounter() 783 b := CPU.RTCounter() 784 t.Log("CPU Counter:", a, b, b-a) 785} 786 787// Prints the value of Ia32TscAux() 788func TestIa32TscAux(t *testing.T) { 789 ecx := CPU.Ia32TscAux() 790 t.Logf("Ia32TscAux:0x%x\n", ecx) 791 if ecx != 0 { 792 chip := (ecx & 0xFFF000) >> 12 793 core := ecx & 0xFFF 794 t.Log("Likely chip, core:", chip, core) 795 } 796} 797 798func TestThreadsPerCoreNZ(t *testing.T) { 799 if CPU.ThreadsPerCore == 0 { 800 t.Fatal("threads per core is zero") 801 } 802} 803 804// Prints the value of LogicalCPU() 805func TestLogicalCPU(t *testing.T) { 806 t.Log("Currently executing on cpu:", CPU.LogicalCPU()) 807} 808 809func TestMaxFunction(t *testing.T) { 810 expect := maxFunctionID() 811 if CPU.maxFunc != expect { 812 t.Fatal("Max function does not match, expected", expect, "but got", CPU.maxFunc) 813 } 814 expect = maxExtendedFunction() 815 if CPU.maxExFunc != expect { 816 t.Fatal("Max Extended function does not match, expected", expect, "but got", CPU.maxFunc) 817 } 818} 819 820// This example will calculate the chip/core number on Linux 821// Linux encodes numa id (<<12) and core id (8bit) into TSC_AUX. 822func ExampleCPUInfo_Ia32TscAux() { 823 ecx := CPU.Ia32TscAux() 824 if ecx == 0 { 825 fmt.Println("Unknown CPU ID") 826 return 827 } 828 chip := (ecx & 0xFFF000) >> 12 829 core := ecx & 0xFFF 830 fmt.Println("Chip, Core:", chip, core) 831} 832 833/* 834func TestPhysical(t *testing.T) { 835 var test16 = "CPUID 00000000: 0000000d-756e6547-6c65746e-49656e69 \nCPUID 00000001: 000206d7-03200800-1fbee3ff-bfebfbff \nCPUID 00000002: 76035a01-00f0b2ff-00000000-00ca0000 \nCPUID 00000003: 00000000-00000000-00000000-00000000 \nCPUID 00000004: 3c004121-01c0003f-0000003f-00000000 \nCPUID 00000004: 3c004122-01c0003f-0000003f-00000000 \nCPUID 00000004: 3c004143-01c0003f-000001ff-00000000 \nCPUID 00000004: 3c07c163-04c0003f-00003fff-00000006 \nCPUID 00000005: 00000040-00000040-00000003-00021120 \nCPUID 00000006: 00000075-00000002-00000009-00000000 \nCPUID 00000007: 00000000-00000000-00000000-00000000 \nCPUID 00000008: 00000000-00000000-00000000-00000000 \nCPUID 00000009: 00000001-00000000-00000000-00000000 \nCPUID 0000000a: 07300403-00000000-00000000-00000603 \nCPUID 0000000b: 00000000-00000000-00000003-00000003 \nCPUID 0000000b: 00000005-00000010-00000201-00000003 \nCPUID 0000000c: 00000000-00000000-00000000-00000000 \nCPUID 0000000d: 00000007-00000340-00000340-00000000 \nCPUID 0000000d: 00000001-00000000-00000000-00000000 \nCPUID 0000000d: 00000100-00000240-00000000-00000000 \nCPUID 80000000: 80000008-00000000-00000000-00000000 \nCPUID 80000001: 00000000-00000000-00000001-2c100800 \nCPUID 80000002: 20202020-49202020-6c65746e-20295228 \nCPUID 80000003: 6e6f6558-20295228-20555043-322d3545 \nCPUID 80000004: 20303636-20402030-30322e32-007a4847 \nCPUID 80000005: 00000000-00000000-00000000-00000000 \nCPUID 80000006: 00000000-00000000-01006040-00000000 \nCPUID 80000007: 00000000-00000000-00000000-00000100 \nCPUID 80000008: 0000302e-00000000-00000000-00000000" 836 restore := mockCPU([]byte(test16)) 837 Detect() 838 t.Log("Name:", CPU.BrandName) 839 n := maxFunctionID() 840 t.Logf("Max Function:0x%x\n", n) 841 n = maxExtendedFunction() 842 t.Logf("Max Extended Function:0x%x\n", n) 843 t.Log("PhysicalCores:", CPU.PhysicalCores) 844 t.Log("ThreadsPerCore:", CPU.ThreadsPerCore) 845 t.Log("LogicalCores:", CPU.LogicalCores) 846 t.Log("Family", CPU.Family, "Model:", CPU.Model) 847 t.Log("Features:", CPU.Features) 848 t.Log("Cacheline bytes:", CPU.CacheLine) 849 t.Log("L1 Instruction Cache:", CPU.Cache.L1I, "bytes") 850 t.Log("L1 Data Cache:", CPU.Cache.L1D, "bytes") 851 t.Log("L2 Cache:", CPU.Cache.L2, "bytes") 852 t.Log("L3 Cache:", CPU.Cache.L3, "bytes") 853 if CPU.LogicalCores > 0 && CPU.PhysicalCores > 0 { 854 if CPU.LogicalCores != CPU.PhysicalCores*CPU.ThreadsPerCore { 855 t.Fatalf("Core count mismatch, LogicalCores (%d) != PhysicalCores (%d) * CPU.ThreadsPerCore (%d)", 856 CPU.LogicalCores, CPU.PhysicalCores, CPU.ThreadsPerCore) 857 } 858 } 859 860 if CPU.ThreadsPerCore > 1 && !CPU.HTT() { 861 t.Fatalf("Hyperthreading not detected") 862 } 863 if CPU.ThreadsPerCore == 1 && CPU.HTT() { 864 t.Fatalf("Hyperthreading detected, but only 1 Thread per core") 865 } 866 restore() 867 Detect() 868 TestCPUID(t) 869} 870*/ 871