Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions src/Prefetch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -433,9 +433,18 @@ Stmt reduce_prefetch_dimension(Stmt stmt, const Target &t) {
// two dimension. Other architectures generate one prefetch per cache line.
if (t.has_feature(Target::HVX)) {
max_dim = 2;
} else if (t.arch == Target::ARM && t.bits == 64 &&
(t.os == Target::MacOS || t.os == Target::IOS)) {
// Apple's 64-bit ARM cores have 128-byte cache lines.
max_dim = 1;
max_byte_size = 128;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of curiosity, have you tried 256 instead of 128?

Context: not long ago I wrote a benchmark, and found out that even though the cache line size of Apple Silicon is 128 bytes long, for false-sharing scenarios, using 256 bytes gave better performance still.

Curious to see if it would have an effect here.

} else if (t.arch == Target::ARM && t.bits == 64) {
// 64-bit ARM cores have cache lines of at least 64 bytes.
max_dim = 1;
max_byte_size = 64;
} else if (t.arch == Target::ARM) {
// ARM's cache line size can be 32 or 64 bytes and it can switch the
// size at runtime. To be safe, we just use 32 bytes.
// 32-bit ARM's cache line size can be 32 or 64 bytes and it can
// switch the size at runtime. To be safe, we just use 32 bytes.
max_dim = 1;
max_byte_size = 32;
} else {
Expand Down
32 changes: 24 additions & 8 deletions test/correctness/prefetch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ Expr get_max_byte_size(const Target &t) {
Expr max_byte_size;
if (t.has_feature(Target::HVX)) {
max_byte_size = Expr();
} else if (t.arch == Target::ARM && t.bits == 64 &&
(t.os == Target::MacOS || t.os == Target::IOS)) {
max_byte_size = 128;
} else if (t.arch == Target::ARM && t.bits == 64) {
max_byte_size = 64;
} else if (t.arch == Target::ARM) {
max_byte_size = 32;
} else {
Expand Down Expand Up @@ -472,18 +477,29 @@ int test12(const Target &t) {
} // anonymous namespace

int main(int argc, char **argv) {
Target t = get_jit_target_from_environment();
std::cout << "Testing target: " << t << "\n";
// These tests only lower, so we can also check the prefetch splitting of
// targets other than the host.
std::vector<Target> targets = {
get_jit_target_from_environment(),
Target("x86-64-linux"),
Target("arm-32-linux"),
Target("arm-64-linux"),
Target("arm-64-macos"),
Target("arm-64-ios"),
};

using Fn = int (*)(const Target &t);
std::vector<Fn> tests = {test1, test2, test3, test4, test5, test6, test7, test8, test9, test10, test11, test12};

for (size_t i = 0; i < tests.size(); i++) {
printf("Running prefetch test %d\n", (int)i + 1);
int result = tests[i](t);
if (result != 0) {
printf(" prefetch test %d failed!\n", (int)i + 1);
return result;
for (const Target &t : targets) {
std::cout << "Testing target: " << t << "\n";
for (size_t i = 0; i < tests.size(); i++) {
printf("Running prefetch test %d\n", (int)i + 1);
int result = tests[i](t);
if (result != 0) {
printf(" prefetch test %d failed!\n", (int)i + 1);
return result;
}
}
}

Expand Down
Loading