| ... | @@ -408,79 +408,87 @@ test spinLoopHint { | ... | @@ -408,79 +408,87 @@ test spinLoopHint { |
| 408 | } | 408 | } |
| 409 | } | 409 | } |
| 410 | | 410 | |
| | 411 | pub fn cacheLineForCpu(cpu: std.Target.Cpu) u16 { |
| | 412 | return switch (cpu.arch) { |
| | 413 | // x86_64: Starting from Intel's Sandy Bridge, the spatial prefetcher pulls in pairs of 64-byte cache lines at a time. |
| | 414 | // - https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-optimization-manual.pdf |
| | 415 | // - https://github.com/facebook/folly/blob/1b5288e6eea6df074758f877c849b6e73bbb9fbb/folly/lang/Align.h#L107 |
| | 416 | // |
| | 417 | // aarch64: Some big.LITTLE ARM archs have "big" cores with 128-byte cache lines: |
| | 418 | // - https://www.mono-project.com/news/2016/09/12/arm64-icache/ |
| | 419 | // - https://cpufun.substack.com/p/more-m1-fun-hardware-information |
| | 420 | // |
| | 421 | // - https://github.com/torvalds/linux/blob/3a7e02c040b130b5545e4b115aada7bacd80a2b6/arch/arc/Kconfig#L212 |
| | 422 | // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_ppc64x.go#L9 |
| | 423 | .x86_64, |
| | 424 | .aarch64, |
| | 425 | .aarch64_be, |
| | 426 | .arc, |
| | 427 | .powerpc64, |
| | 428 | .powerpc64le, |
| | 429 | => 128, |
| | 430 | |
| | 431 | // https://github.com/llvm/llvm-project/blob/e379094328e49731a606304f7e3559d4f1fa96f9/clang/lib/Basic/Targets/Hexagon.h#L145-L151 |
| | 432 | .hexagon, |
| | 433 | => if (std.Target.hexagon.featureSetHas(cpu.features, .v73)) 64 else 32, |
| | 434 | |
| | 435 | // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_arm.go#L7 |
| | 436 | // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_mips.go#L7 |
| | 437 | // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_mipsle.go#L7 |
| | 438 | // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_mips64x.go#L9 |
| | 439 | // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_riscv64.go#L7 |
| | 440 | // - https://github.com/torvalds/linux/blob/3a7e02c040b130b5545e4b115aada7bacd80a2b6/arch/sparc/include/asm/cache.h#L14 |
| | 441 | .arm, |
| | 442 | .armeb, |
| | 443 | .thumb, |
| | 444 | .thumbeb, |
| | 445 | .mips, |
| | 446 | .mipsel, |
| | 447 | .mips64, |
| | 448 | .mips64el, |
| | 449 | .riscv32, |
| | 450 | .riscv64, |
| | 451 | .sparc, |
| | 452 | .sparc64, |
| | 453 | => 32, |
| | 454 | |
| | 455 | // - https://github.com/torvalds/linux/blob/3a7e02c040b130b5545e4b115aada7bacd80a2b6/arch/m68k/include/asm/cache.h#L10 |
| | 456 | .m68k, |
| | 457 | => 16, |
| | 458 | |
| | 459 | // - https://www.ti.com/lit/pdf/slaa498 |
| | 460 | .msp430, |
| | 461 | => 8, |
| | 462 | |
| | 463 | // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_s390x.go#L7 |
| | 464 | // - https://sxauroratsubasa.sakura.ne.jp/documents/guide/pdfs/Aurora_ISA_guide.pdf |
| | 465 | .s390x, |
| | 466 | .ve, |
| | 467 | => 256, |
| | 468 | |
| | 469 | // Other x86 and WASM platforms have 64-byte cache lines. |
| | 470 | // The rest of the architectures are assumed to be similar. |
| | 471 | // - https://github.com/golang/go/blob/dda2991c2ea0c5914714469c4defc2562a907230/src/internal/cpu/cpu_x86.go#L9 |
| | 472 | // - https://github.com/golang/go/blob/0a9321ad7f8c91e1b0c7184731257df923977eb9/src/internal/cpu/cpu_loong64.go#L11 |
| | 473 | // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_wasm.go#L7 |
| | 474 | // - https://github.com/torvalds/linux/blob/3a7e02c040b130b5545e4b115aada7bacd80a2b6/arch/xtensa/variants/csp/include/variant/core.h#L209 |
| | 475 | // - https://github.com/torvalds/linux/blob/3a7e02c040b130b5545e4b115aada7bacd80a2b6/arch/csky/Kconfig#L183 |
| | 476 | // - https://www.xmos.com/download/The-XMOS-XS3-Architecture.pdf |
| | 477 | else => 64, |
| | 478 | }; |
| | 479 | } |
| | 480 | |
| 411 | /// The estimated size of the CPU's cache line when atomically updating memory. | 481 | /// The estimated size of the CPU's cache line when atomically updating memory. |
| 412 | /// Add this much padding or align to this boundary to avoid atomically-updated | 482 | /// Add this much padding or align to this boundary to avoid atomically-updated |
| 413 | /// memory from forcing cache invalidations on near, but non-atomic, memory. | 483 | /// memory from forcing cache invalidations on near, but non-atomic, memory. |
| 414 | /// | 484 | /// |
| 415 | /// https://en.wikipedia.org/wiki/False_sharing | 485 | /// https://en.wikipedia.org/wiki/False_sharing |
| 416 | /// https://github.com/golang/go/search?q=CacheLinePadSize | 486 | /// https://github.com/golang/go/search?q=CacheLinePadSize |
| 417 | pub const cache_line = switch (builtin.cpu.arch) { | 487 | pub const cache_line = cacheLineForCpu(builtin.cpu); |
| 418 | // x86_64: Starting from Intel's Sandy Bridge, the spatial prefetcher pulls in pairs of 64-byte cache lines at a time. | 488 | |
| 419 | // - https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-optimization-manual.pdf | 489 | test "current CPU has a cache line size" { |
| 420 | // - https://github.com/facebook/folly/blob/1b5288e6eea6df074758f877c849b6e73bbb9fbb/folly/lang/Align.h#L107 | 490 | _ = cache_line; |
| 421 | // | 491 | } |
| 422 | // aarch64: Some big.LITTLE ARM archs have "big" cores with 128-byte cache lines: | | |
| 423 | // - https://www.mono-project.com/news/2016/09/12/arm64-icache/ | | |
| 424 | // - https://cpufun.substack.com/p/more-m1-fun-hardware-information | | |
| 425 | // | | |
| 426 | // - https://github.com/torvalds/linux/blob/3a7e02c040b130b5545e4b115aada7bacd80a2b6/arch/arc/Kconfig#L212 | | |
| 427 | // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_ppc64x.go#L9 | | |
| 428 | .x86_64, | | |
| 429 | .aarch64, | | |
| 430 | .aarch64_be, | | |
| 431 | .arc, | | |
| 432 | .powerpc64, | | |
| 433 | .powerpc64le, | | |
| 434 | => 128, | | |
| 435 | | | |
| 436 | // https://github.com/llvm/llvm-project/blob/e379094328e49731a606304f7e3559d4f1fa96f9/clang/lib/Basic/Targets/Hexagon.h#L145-L151 | | |
| 437 | .hexagon, | | |
| 438 | => if (std.Target.hexagon.featureSetHas(builtin.target.cpu.features, .v73)) 64 else 32, | | |
| 439 | | | |
| 440 | // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_arm.go#L7 | | |
| 441 | // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_mips.go#L7 | | |
| 442 | // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_mipsle.go#L7 | | |
| 443 | // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_mips64x.go#L9 | | |
| 444 | // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_riscv64.go#L7 | | |
| 445 | // - https://github.com/torvalds/linux/blob/3a7e02c040b130b5545e4b115aada7bacd80a2b6/arch/sparc/include/asm/cache.h#L14 | | |
| 446 | .arm, | | |
| 447 | .armeb, | | |
| 448 | .thumb, | | |
| 449 | .thumbeb, | | |
| 450 | .mips, | | |
| 451 | .mipsel, | | |
| 452 | .mips64, | | |
| 453 | .mips64el, | | |
| 454 | .riscv32, | | |
| 455 | .riscv64, | | |
| 456 | .sparc, | | |
| 457 | .sparc64, | | |
| 458 | => 32, | | |
| 459 | | | |
| 460 | // - https://github.com/torvalds/linux/blob/3a7e02c040b130b5545e4b115aada7bacd80a2b6/arch/m68k/include/asm/cache.h#L10 | | |
| 461 | .m68k, | | |
| 462 | => 16, | | |
| 463 | | | |
| 464 | // - https://www.ti.com/lit/pdf/slaa498 | | |
| 465 | .msp430, | | |
| 466 | => 8, | | |
| 467 | | | |
| 468 | // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_s390x.go#L7 | | |
| 469 | // - https://sxauroratsubasa.sakura.ne.jp/documents/guide/pdfs/Aurora_ISA_guide.pdf | | |
| 470 | .s390x, | | |
| 471 | .ve, | | |
| 472 | => 256, | | |
| 473 | | | |
| 474 | // Other x86 and WASM platforms have 64-byte cache lines. | | |
| 475 | // The rest of the architectures are assumed to be similar. | | |
| 476 | // - https://github.com/golang/go/blob/dda2991c2ea0c5914714469c4defc2562a907230/src/internal/cpu/cpu_x86.go#L9 | | |
| 477 | // - https://github.com/golang/go/blob/0a9321ad7f8c91e1b0c7184731257df923977eb9/src/internal/cpu/cpu_loong64.go#L11 | | |
| 478 | // - https://github.com/golang/go/blob/3dd58676054223962cd915bb0934d1f9f489d4d2/src/internal/cpu/cpu_wasm.go#L7 | | |
| 479 | // - https://github.com/torvalds/linux/blob/3a7e02c040b130b5545e4b115aada7bacd80a2b6/arch/xtensa/variants/csp/include/variant/core.h#L209 | | |
| 480 | // - https://github.com/torvalds/linux/blob/3a7e02c040b130b5545e4b115aada7bacd80a2b6/arch/csky/Kconfig#L183 | | |
| 481 | // - https://www.xmos.com/download/The-XMOS-XS3-Architecture.pdf | | |
| 482 | else => 64, | | |
| 483 | }; | | |
| 484 | | 492 | |
| 485 | const std = @import("std.zig"); | 493 | const std = @import("std.zig"); |
| 486 | const builtin = @import("builtin"); | 494 | const builtin = @import("builtin"); |