From 73bf552cd6e517bd96589dd83086b80be83172f8 Mon Sep 17 00:00:00 2001 From: Matt Pharr Date: Fri, 10 Feb 2012 12:46:59 -0800 Subject: [PATCH] Add support for coalescing memory accesses from gathers. There are two related optimizations that happen now. (These currently only apply for gathers where the mask is known to be all on, and to gathers that are accessing 32-bit sized elements, but both of these may be generalized in the future.) First, for any single gather, we are now more flexible in mapping it to individual memory operations. Previously, we would only either map it to a general gather (one scalar load per SIMD lane), or an unaligned vector load (if the program instances could be determined to be accessing a sequential set of locations in memory.) Now, we are able to break gathers into scalar, 2-wide (i.e. 64-bit), 4-wide, or 8-wide loads. Further, we now generate code that shuffles these loads around. Doing fewer, larger loads in this manner, when possible, can be more efficient. Second, we can coalesce memory accesses across multiple gathers. If we have a series of gathers without any memory writes in the middle, then we try to analyze their reads collectively and choose an efficient set of loads for them. Not only does this help if different gathers reuse values from the same location in memory, but it's specifically helpful when data with AOS layout is being accessed; in this case, we're often able to generate wide vector loads and appropriate shuffles automatically. --- ispc.cpp | 1 + ispc.h | 4 + main.cpp | 11 +- opt.cpp | 1156 ++++++++++++++++++++++++++++++++++++++++- tests/coalesce-1.ispc | 14 + tests/coalesce-2.ispc | 14 + tests/coalesce-3.ispc | 14 + tests/coalesce-4.ispc | 17 + tests/coalesce-5.ispc | 20 + tests/coalesce-6.ispc | 21 + tests/coalesce-7.ispc | 21 + tests/coalesce-8.ispc | 19 + 12 files changed, 1307 insertions(+), 5 deletions(-) create mode 100644 tests/coalesce-1.ispc create mode 100644 tests/coalesce-2.ispc create mode 100644 tests/coalesce-3.ispc create mode 100644 tests/coalesce-4.ispc create mode 100644 tests/coalesce-5.ispc create mode 100644 tests/coalesce-6.ispc create mode 100644 tests/coalesce-7.ispc create mode 100644 tests/coalesce-8.ispc diff --git a/ispc.cpp b/ispc.cpp index 6729da92..49623be4 100644 --- a/ispc.cpp +++ b/ispc.cpp @@ -497,6 +497,7 @@ Opt::Opt() { disableMaskedStoreToStore = false; disableGatherScatterFlattening = false; disableUniformMemoryOptimizations = false; + disableCoalescing = false; } /////////////////////////////////////////////////////////////////////////// diff --git a/ispc.h b/ispc.h index 59c9140f..c28a9f67 100644 --- a/ispc.h +++ b/ispc.h @@ -339,6 +339,10 @@ struct Opt { than gathers/scatters. This is likely only useful for measuring the impact of this optimization. */ bool disableUniformMemoryOptimizations; + + /** Disables optimizations that coalesce incoherent scalar memory + access from gathers into wider vector operations, when possible. */ + bool disableCoalescing; }; /** @brief This structure collects together a number of global variables. diff --git a/main.cpp b/main.cpp index 7b8c66d5..faee437f 100644 --- a/main.cpp +++ b/main.cpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2010-2011, Intel Corporation + Copyright (c) 2010-2012, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -141,16 +141,17 @@ devUsage(int ret) { printf(" [--fuzz-test]\t\t\tRandomly perturb program input to test error conditions\n"); printf(" [--fuzz-seed=]\t\tSeed value for RNG for fuzz testing\n"); printf(" [--opt=