Skip to content
Open
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
60 changes: 30 additions & 30 deletions gs_patterns.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,16 @@
#define OBOUNDS_ALLOC (2*OBOUNDS + 3)

//patterns
#define USTRIDES 1024 //Threshold for number of accesses
#define NSTRIDES 15 //Threshold for number of unique distances
#define OUTTHRESH (0.5) //Threshold for percentage of distances at boundaries of histogram
#define DEFAULT_THRESHOLD_USTRIDES 1024 //Default Threshold for number of accesses
#define DEFAULT_THRESHOLD_NSTRIDES 15 //Default Threshold for number of unique distances
#define DEFAULT_THRESHOLD_OUT_DIST_PERCENT (0.5) //Default Threshold for percentage of distances at boundaries of histogram

#define NTOP (10) //Final gather / scatters to keep
#define INITIAL_PSIZE (1<<15)
#define MAX_PSIZE (1<<30) //Max number of indices recorded per gather/scatter

#define MAX_LINE_LENGTH 1024

#if !defined(VBITS)
# define VBITS (512L)
# define VBYTES (VBITS/8)
#endif

namespace gs_patterns
{
typedef uintptr_t addr_t;
Expand Down Expand Up @@ -163,21 +159,21 @@ namespace gs_patterns
Metrics(const Metrics &) = delete;
Metrics & operator=(const Metrics & right) = delete;

std::string type_as_string() { return !_mType ? "GATHER" : "SCATTER"; }
std::string getName() { return !_mType ? "Gather" : "Scatter"; }
std::string getShortName() { return !_mType ? "G" : "S"; }
std::string getShortNameLower() { return !_mType ? "g" : "s"; }
std::string type_as_string() { return !_mType ? "GATHER" : "SCATTER"; }
std::string getName() { return !_mType ? "Gather" : "Scatter"; }
std::string getShortName() { return !_mType ? "G" : "S"; }
std::string getShortNameLower() { return !_mType ? "g" : "s"; }

auto get_srcline() { return srcline[_mType]; }

int ntop = 0;
int64_t iaddrs_nosym = 0;
int64_t iaddrs_nosym = 0;
int64_t indices_nosym = 0;
int64_t iaddrs_sym = 0;
int64_t indices_sym = 0;
int64_t iaddrs_sym = 0;
int64_t indices_sym = 0;
double cnt = 0.0;
int offset[NTOP] = {0};
int size[NTOP] = {0};
int size[NTOP] = {0};

addr_t tot[NTOP] = {0};
addr_t top[NTOP] = {0};
Expand Down Expand Up @@ -263,24 +259,18 @@ namespace gs_patterns

void init() {
for (int w = 0; w < 2; w++) {
for (int i = 0; i < IWINDOW; i++) {
_w_iaddrs[w][i] = -1;
_w_bytes[w][i] = 0;
_w_cnt[w][i] = 0;
for (uint64_t j = 0; j < MAX_ACCESS_SIZE; j++)
_w_maddr[w][i][j] = -1;
}
memset(_w_iaddrs[w], 0xFF, IWINDOW * sizeof(int64_t));
memset(_w_bytes[w], 0x00, IWINDOW * sizeof(int64_t));
memset(_w_cnt[w], 0x00, IWINDOW * sizeof(int64_t));
memset(&_w_maddr[w][0][0], 0xFF, IWINDOW * MAX_ACCESS_SIZE * sizeof(int64_t));
}
}

void reset(int w) {
for (int i = 0; i < IWINDOW; i++) {
_w_iaddrs[w][i] = -1;
_w_bytes[w][i] = 0;
_w_cnt[w][i] = 0;
for (uint64_t j = 0; j < MAX_ACCESS_SIZE; j++)
_w_maddr[w][i][j] = -1;
}
memset(_w_iaddrs[w], 0xFF, IWINDOW * sizeof(int64_t));
memset(_w_bytes[w], 0x00, IWINDOW * sizeof(int64_t));
memset(_w_cnt[w], 0x00, IWINDOW * sizeof(int64_t));
memset(&_w_maddr[w][0][0], 0xFF, IWINDOW * MAX_ACCESS_SIZE * sizeof(int64_t));
}

void reset() {
Expand Down Expand Up @@ -314,6 +304,14 @@ namespace gs_patterns
int64_t maddr;
};

struct Thresholds
{
// Defaults set here, but potentially overrided
int num_accesses = DEFAULT_THRESHOLD_USTRIDES;
int num_strides = DEFAULT_THRESHOLD_NSTRIDES;
float out_dist_percent = DEFAULT_THRESHOLD_OUT_DIST_PERCENT;
};

template <std::size_t MAX_ACCESS_SIZE>
class MemPatterns
{
Expand All @@ -339,6 +337,8 @@ namespace gs_patterns
get_instr_window() = 0;
virtual void set_log_level(int8_t ll) = 0;
virtual int8_t get_log_level() = 0;

virtual Thresholds & get_thresholds() = 0;
};

} // namespace gs_patterns
157 changes: 7 additions & 150 deletions gs_patterns_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,159 +39,16 @@ namespace gs_patterns_core

return;
}

void create_metrics_file(FILE * fp, FILE * fp2, const std::string & file_prefix, Metrics & target_metrics, bool & first_spatter)
{
int i = 0;
int j = 0;

//Create stride histogram and create spatter
int sidx;
int firstgs = 1;
int unique_strides;
int64_t hbin = 0;
int64_t n_stride[OBOUNDS_ALLOC];
double outbounds;

if (file_prefix.empty()) throw GSFileError ("Empty file prefix provided.");

if (first_spatter) printf("\n");

printf("\n");
for (i = 0; i < target_metrics.ntop; i++) {
printf("***************************************************************************************\n");

unique_strides = 0;
for (j = 0; j < OBOUNDS_ALLOC; j++)
n_stride[j] = 0;

for (j = 1; j < target_metrics.offset[i]; j++) {
sidx = target_metrics.patterns[i][j] - target_metrics.patterns[i][j - 1] + OBOUNDS + 1;
sidx = (sidx < 1) ? 0 : sidx;
sidx = (sidx > OBOUNDS_ALLOC - 1) ? OBOUNDS_ALLOC - 1 : sidx;
n_stride[sidx]++;
}

for (j = 0; j < OBOUNDS_ALLOC; j++) {
if (n_stride[j] > 0) {
unique_strides++;
}
}

outbounds = (double) (n_stride[0] + n_stride[OBOUNDS_ALLOC-1]) / (double) target_metrics.offset[i];

if (((unique_strides > NSTRIDES) || (outbounds > OUTTHRESH) && (target_metrics.offset[i] > USTRIDES ) )) {
//if (true) {

if (firstgs) {
firstgs = 0;
printf("***************************************************************************************\n");
printf("%sS\n", target_metrics.type_as_string().c_str());
}
printf("***************************************************************************************\n");
//create a binary file
FILE * fp_bin;

char bin_name[1024];
sprintf(bin_name, "%s.%s.%03d.%02dB.sbin", file_prefix.c_str(), target_metrics.getShortNameLower().c_str(), \
i, target_metrics.size[i]);
printf("%s\n", bin_name);
//std::string bin_name = \
// file_prefix + "." + target_metrics.getShortNameLower().c_str() + "." + std::to_string(i) + "." + \
// std::to_string(target_metrics.size[i]) + "B.sbin";

fp_bin = fopen(bin_name, "w");
if (NULL == fp_bin)
throw GSFileError("Could not open " + std::string(bin_name) + "!");

printf("%sIADDR -- %p\n", target_metrics.getShortName().c_str(), (void*) target_metrics.top[i]);
printf("SRCLINE -- %s\n", target_metrics.get_srcline()[target_metrics.top_idx[i]]);
printf("GATHER %c -- %6.3f%c (%4ld-bit chunks)\n",
'%', 100.0 * (double) target_metrics.tot[i] / target_metrics.cnt, '%', VBITS);
printf("DTYPE -- %d bytes\n", target_metrics.size[i]);
printf("NINDICES -- %d\n", target_metrics.offset[i]);
printf("INDICES:\n");

int64_t nlcnt = 0;
for (j = 0; j < target_metrics.offset[i]; j++) {

if (j <= 49) {
printf("%10ld ", target_metrics.patterns[i][j]);
fflush(stdout);
if (( ++nlcnt % 10) == 0)
printf("\n");

} else if (j >= (target_metrics.offset[i] - 50)) {
printf("%10ld ", target_metrics.patterns[i][j]);
fflush(stdout);
if (( ++nlcnt % 10) == 0)
printf("\n");

} else if (j == 50)
printf("...\n");
}
printf("\n");
printf("DIST HISTOGRAM --\n");

hbin = 0;
for(j=0; j<OBOUNDS_ALLOC; j++) {

if (j == 0) {
printf("( -inf, %5ld]: %ld\n", (int64_t)(-(VBITS+1)), n_stride[j]);
hbin = 0;

} else if (j == OBOUNDS +1) {
printf("[%5ld, 0): %ld\n", (int64_t)-VBITS, hbin);
hbin = 0;

} else if (j == (OBOUNDS_ALLOC-2) ) {
printf("[ 0, %5ld]: %ld\n", VBITS, hbin);
hbin = 0;

} else if (j == (OBOUNDS_ALLOC-1)) {
printf("[%5ld, inf): %ld\n", VBITS+1, n_stride[j]);

} else {
hbin += n_stride[j];
}
}

if (first_spatter) {
first_spatter = false;
fprintf(fp, " {\"kernel\":\"%s\", \"pattern\":[", target_metrics.getName().c_str());
} else {
fprintf(fp, ",\n {\"kernel\":\"%s\", \"pattern\":[", target_metrics.getName().c_str());
}

fwrite(target_metrics.patterns[i], sizeof(uint64_t), target_metrics.offset[i], fp_bin);
fclose(fp_bin);

for (j = 0; j < target_metrics.offset[i] - 1; j++)
fprintf(fp, "%ld,", target_metrics.patterns[i][j]);
fprintf(fp, "%ld", target_metrics.patterns[i][target_metrics.offset[i] - 1]);
fprintf(fp, "], \"count\":1}");

fprintf(fp2, "0x%lx,%s,%d,%s,%d,%6.3f\n",
target_metrics.top[i],
target_metrics.get_srcline()[target_metrics.top_idx[i]],
target_metrics.size[i],
target_metrics.getShortName().c_str(),
target_metrics.offset[i],
100.0 * (double) target_metrics.tot[i] / target_metrics.cnt);
}
printf("***************************************************************************************\n\n");
}
}


void normalize_stats(Metrics & target_metrics)
{
//Normalize
int64_t smallest;
for (int i = 0; i < target_metrics.ntop; i++) {

//Find smallest
smallest = 0x7FFFFFFFFFFFFFFFL;
for (int j = 0; j < target_metrics.offset[i]; j++) {
smallest = 0x7FFFFFFFFFFFFFFFL;
for (int j = 0; j < target_metrics.offset[i]; j++) {
if (target_metrics.patterns[i][j] < smallest)
smallest = target_metrics.patterns[i][j];
}
Expand Down Expand Up @@ -297,7 +154,7 @@ namespace gs_patterns_core
if (iaddr == gather_metrics.top[i])
{

gather_metrics.size[i] = ia.get_size();
gather_metrics.size[i] = ia.get_size();

if (gather_base[i] == 0)
gather_base[i] = maddr;
Expand All @@ -307,7 +164,7 @@ namespace gs_patterns_core
if (!gather_metrics.grow(i)) {
printf("WARNING: Unable to increase PSIZE. Truncating trace...\n");
breakout = true;
break;
break;
}
}
gather_metrics.patterns[i][gather_metrics.offset[i]++] = (int64_t) (maddr - gather_base[i]);
Expand All @@ -323,7 +180,7 @@ namespace gs_patterns_core
//found it
if (iaddr == scatter_metrics.top[i])
{
scatter_metrics.size[i] = ia.get_size();
scatter_metrics.size[i] = ia.get_size();

//set base
if (scatter_base[i] == 0)
Expand All @@ -334,7 +191,7 @@ namespace gs_patterns_core
if (!scatter_metrics.grow(i)) {
printf("WARNING: Unable to increase PSIZE. Truncating trace...\n");
breakout = true;
break;
break;
}
}
scatter_metrics.patterns[i][scatter_metrics.offset[i]++] = (int64_t) (maddr - scatter_base[i]);
Expand Down
Loading