File pipelined.h
File List > arbitrator > pipelined.h
Go to the documentation of this file
#pragma once
#include <simtix/param.h>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "simtix/sm.h"
#include "sm/arbitrator/base.h"
namespace simtix {
// Class: PipelinedArbitrator
class PipelinedArbitrator : public BaseArbitrator {
public:
struct Request {
const std::vector<Thread *> *active_threads;
uint32_t reg_id;
int64_t *data_arr;
int64_t data;
OnReady on_ready;
bool is_write;
uint32_t req_bank;
Request(const std::vector<Thread *> *active_threads, uint32_t reg_id,
int64_t *data_arr, int64_t data, OnReady on_ready, bool is_write,
uint32_t req_bank)
: active_threads(active_threads),
reg_id(reg_id),
data_arr(data_arr),
data(data),
on_ready(std::move(on_ready)),
is_write(is_write),
req_bank(req_bank) {}
};
explicit PipelinedArbitrator(const std::string &name, const ArchParam &p,
const pipelined::PipelinedSM::Param &pp);
~PipelinedArbitrator() = default;
void PushRegfileReadReq(const std::vector<Thread *> &active_threads,
uint32_t reg_id, int64_t *data,
OnReady on_ready) override;
void PushRegfileWriteReq(const std::vector<Thread *> &active_threads,
uint32_t reg_id, int64_t *data,
OnReady on_ready) override;
void PushRegfileWriteReq(const std::vector<Thread *> &active_threads,
uint32_t reg_id, int64_t data,
OnReady on_ready) override;
int64_t ReadRegfile(uint32_t wid, uint32_t tid, uint32_t reg_id) override {
return regfile_[ToRegfileIndex(wid, tid, reg_id)] * (reg_id != 0);
}
void WriteRegfile(uint32_t wid, uint32_t tid, uint32_t reg_id,
int64_t data) override {
regfile_[ToRegfileIndex(wid, tid, reg_id)] = data * (reg_id != 0);
}
void ArbitrateReq();
void Reset();
void ResetStat() { stat_ = std::make_shared<Stat>(name_); }
const std::shared_ptr<stat::Group> stat() const { return stat_; }
protected:
struct Stat : stat::Group {
explicit Stat(const std::string &s)
: Group(s),
STAT(bank_conflict, "Number of bank conflicts", "N/A"),
STAT(bank_available, "Number of available banks when request is sent",
"N/A"),
STAT(total_write_requests,
"Total number of write requests send to banked regfile", "N/A"),
STAT(total_read_requests,
"Total number of read requests send to banked regfile", "N/A"),
STAT(forwarded_requests, "Number of forwarded requests", "N/A"),
STAT(total_requests,
"Total number of requests send to banked regfile", "N/A"),
STAT(bank_utilization, "Bank utilization of banked regfile", "N/A") {
total_requests = total_write_requests + total_read_requests;
bank_utilization = forwarded_requests / bank_available;
}
stat::Integer bank_conflict;
stat::Integer bank_available;
stat::Integer total_write_requests;
stat::Integer total_read_requests;
stat::Integer forwarded_requests;
stat::Formula<stat::Integer> total_requests;
stat::Formula<stat::Real> bank_utilization;
};
std::shared_ptr<Stat> stat_;
private:
const std::string name_;
const uint32_t kThreadsPerWarp;
const uint32_t kWarpsPerCore;
const uint32_t kWarpsPerWarpGroup;
const bool kSwizzle;
const size_t kSharedPorts;
const size_t kReadPorts;
const size_t kWritePorts;
const uint32_t kRegfileBanks;
uint32_t ToRegfileBank(uint32_t wid, uint32_t reg_id);
uint32_t ToRegfileIndex(uint32_t wid, uint32_t tid, uint32_t reg_id);
void AccessRegfile(Request req);
std::vector<int64_t> regfile_;
std::vector<std::vector<Request> *> req_buf_arr_;
std::vector<std::vector<Request>> req_buf_;
std::vector<Request> *read_req_buf_;
std::vector<Request> *write_req_buf_;
std::vector<std::vector<size_t> *> bank_mask_arr_;
std::vector<std::vector<size_t>> bank_mask_;
std::vector<size_t> *read_bank_mask_;
std::vector<size_t> *write_bank_mask_;
};
} // namespace simtix