Browse Source

feat: make chunk_max_size non-virtual

This allows to completely eliminate virtual call overhead for functions
that usually return a constant number
pull/2274/head
Alexander Romanov 1 month ago
parent
commit
3caf790c80
  1. 17
      fesvr/dtm.cc
  2. 2
      fesvr/dtm.h
  3. 14
      fesvr/htif.cc
  4. 9
      fesvr/htif.h
  5. 9
      fesvr/htif_hexwriter.cc
  6. 6
      fesvr/htif_hexwriter.h
  7. 2
      fesvr/htif_pthread.cc
  8. 3
      fesvr/htif_pthread.h
  9. 10
      fesvr/memif.cc
  10. 8
      fesvr/memif.h
  11. 6
      fesvr/tsi.cc
  12. 4
      fesvr/tsi.h
  13. 2
      riscv/sim.cc
  14. 2
      riscv/sim.h

17
fesvr/dtm.cc

@ -213,11 +213,6 @@ uint32_t dtm_t::run_abstract_command(uint32_t command,
}
size_t dtm_t::chunk_align()
{
return xlen / 8;
}
void dtm_t::read_chunk(uint64_t taddr, size_t len, void* dst)
{
uint32_t prog[MAX_PROG_WORDS];
@ -468,12 +463,6 @@ uint64_t dtm_t::modify_csr(unsigned which, uint64_t data, uint32_t type)
return res;
}
size_t dtm_t::chunk_max_size()
{
// Arbitrary choice. 4k Page size seems reasonable.
return 4096;
}
uint32_t dtm_t::get_xlen()
{
// Attempt to read S0 to find out what size it is.
@ -601,9 +590,13 @@ void dtm_t::start_host_thread()
}
dtm_t::dtm_t(int argc, char** argv)
: htif_t(argc, argv), running(false)
// Arbitrary choice. 4k Page size seems reasonable.
: htif_t(argc, argv, /*chunk_max_size=*/4096, /*chunk_align=*/8), running(false)
{
start_host_thread();
// Here we reset chunk_align because we can't call get_xlen in the
// base class constructor
chunk_align = get_xlen() / 8;
}
dtm_t::~dtm_t()

2
fesvr/dtm.h

@ -65,8 +65,6 @@ class dtm_t : public htif_t
virtual void read_chunk(addr_t taddr, size_t len, void* dst) override;
virtual void write_chunk(addr_t taddr, size_t len, const void* src) override;
virtual void clear_chunk(addr_t taddr, size_t len) override;
virtual size_t chunk_align() override;
virtual size_t chunk_max_size() override;
virtual void reset() override;
virtual void idle() override;

14
fesvr/htif.cc

@ -53,8 +53,8 @@ static void handle_signal(int sig)
signal(sig, &handle_signal);
}
htif_t::htif_t()
: mem(this), entry(DRAM_BASE), sig_addr(0), sig_len(0),
htif_t::htif_t(size_t chunk_max_sz, size_t chunk_al)
: chunked_memif_t(chunk_max_sz, chunk_al), mem(this), entry(DRAM_BASE), sig_addr(0), sig_len(0),
tohost_addr(0), fromhost_addr(0), stopped(false),
syscall_proxy(this)
{
@ -63,7 +63,7 @@ htif_t::htif_t()
signal(SIGABRT, &handle_signal); // we still want to call static destructors
}
htif_t::htif_t(int argc, char** argv) : htif_t()
htif_t::htif_t(int argc, char** argv, size_t chunk_max_sz, size_t chunk_al) : htif_t(chunk_max_sz, chunk_al)
{
//Set line size as 16 by default.
line_size = 16;
@ -71,7 +71,7 @@ htif_t::htif_t(int argc, char** argv) : htif_t()
register_devices();
}
htif_t::htif_t(const std::vector<std::string>& args) : htif_t()
htif_t::htif_t(const std::vector<std::string>& args, size_t chunk_max_sz, size_t chunk_al) : htif_t(chunk_max_sz, chunk_al)
{
int argc = args.size() + 1;
std::vector<char*>argv(argc);
@ -275,10 +275,10 @@ void htif_t::stop()
void htif_t::clear_chunk(addr_t taddr, size_t len)
{
std::vector<uint8_t> zeros(chunk_max_size(), 0);
std::vector<uint8_t> zeros(get_chunk_max_size(), 0);
for (size_t pos = 0; pos < len; pos += chunk_max_size())
write_chunk(taddr + pos, std::min(len - pos, chunk_max_size()), &zeros[0]);
for (size_t pos = 0; pos < len; pos += get_chunk_max_size())
write_chunk(taddr + pos, std::min(len - pos, get_chunk_max_size()), &zeros[0]);
}
int htif_t::run()

9
fesvr/htif.h

@ -16,9 +16,9 @@
class htif_t : public chunked_memif_t
{
public:
htif_t();
htif_t(int argc, char** argv);
htif_t(const std::vector<std::string>& args);
htif_t(size_t chunk_max_sz, size_t chunk_al);
htif_t(int argc, char** argv, size_t chunk_max_sz, size_t chunk_al);
htif_t(const std::vector<std::string>& argsm, size_t chunk_max_sz, size_t chunk_al);
virtual ~htif_t();
virtual void start();
@ -59,9 +59,6 @@ class htif_t : public chunked_memif_t
virtual void write_chunk(addr_t taddr, size_t len, const void* src) = 0;
virtual void clear_chunk(addr_t taddr, size_t len);
virtual size_t chunk_align() = 0;
virtual size_t chunk_max_size() = 0;
virtual std::map<std::string, uint64_t> load_payload(const std::string& payload, reg_t* entry,
reg_t load_addr);
virtual void load_program();

9
fesvr/htif_hexwriter.cc

@ -4,16 +4,11 @@
#include <assert.h>
#include "htif_hexwriter.h"
htif_hexwriter_t::htif_hexwriter_t(size_t b, size_t w, size_t d)
: base(b), width(w), depth(d)
{
}
void htif_hexwriter_t::read_chunk(addr_t taddr, size_t len, void* vdst)
{
taddr -= base;
assert(len % chunk_align() == 0);
assert(len % get_chunk_align() == 0);
assert(taddr < width*depth);
assert(taddr+len <= width*depth);
@ -36,7 +31,7 @@ void htif_hexwriter_t::write_chunk(addr_t taddr, size_t len, const void* vsrc)
{
taddr -= base;
assert(len % chunk_align() == 0);
assert(len % get_chunk_align() == 0);
assert(taddr < width*depth);
assert(taddr+len <= width*depth);

6
fesvr/htif_hexwriter.h

@ -11,7 +11,8 @@
class htif_hexwriter_t : public chunked_memif_t
{
public:
htif_hexwriter_t(size_t b, size_t w, size_t d);
htif_hexwriter_t(size_t b, size_t w, size_t d)
: chunked_memif_t(w, w), base(b), width(w), depth(d) {}
protected:
size_t base;
@ -23,9 +24,6 @@ protected:
void write_chunk(addr_t taddr, size_t len, const void* src);
void clear_chunk(addr_t, size_t) {}
size_t chunk_max_size() { return width; }
size_t chunk_align() { return width; }
friend std::ostream& operator<< (std::ostream&, const htif_hexwriter_t&);
};

2
fesvr/htif_pthread.cc

@ -13,7 +13,7 @@ void htif_pthread_t::thread_main(void* arg)
}
htif_pthread_t::htif_pthread_t(int argc, char** argv)
: htif_t(argc, argv)
: htif_t(argc, argv, /*max_sz=*/1024, /*chunk_align=*/64)
{
target = context_t::current();
host.init(thread_main, this);

3
fesvr/htif_pthread.h

@ -23,9 +23,6 @@ class htif_pthread_t : public htif_t
virtual ssize_t read(void* buf, size_t max_size);
virtual ssize_t write(const void* buf, size_t size);
virtual size_t chunk_align() { return 64; }
virtual size_t chunk_max_size() { return 1024; }
private:
context_t host;
context_t* target;

10
fesvr/memif.cc

@ -8,7 +8,7 @@
void memif_t::read(addr_t addr, size_t len, void* bytes)
{
size_t align = cmemif->chunk_align();
size_t align = cmemif->get_chunk_align();
if (len && (addr & (align-1)))
{
size_t this_len = std::min(len, align - size_t(addr & (align-1)));
@ -35,13 +35,13 @@ void memif_t::read(addr_t addr, size_t len, void* bytes)
}
// now we're aligned
for (size_t pos = 0; pos < len; pos += cmemif->chunk_max_size())
cmemif->read_chunk(addr + pos, std::min(cmemif->chunk_max_size(), len - pos), (char*)bytes + pos);
for (size_t pos = 0; pos < len; pos += cmemif->get_chunk_max_size())
cmemif->read_chunk(addr + pos, std::min(cmemif->get_chunk_max_size(), len - pos), (char*)bytes + pos);
}
void memif_t::write(addr_t addr, size_t len, const void* bytes)
{
size_t align = cmemif->chunk_align();
size_t align = cmemif->get_chunk_align();
if (len && (addr & (align-1)))
{
size_t this_len = std::min(len, align - size_t(addr & (align-1)));
@ -77,7 +77,7 @@ void memif_t::write(addr_t addr, size_t len, const void* bytes)
if (all_zero) {
cmemif->clear_chunk(addr, len);
} else {
size_t max_chunk = cmemif->chunk_max_size();
size_t max_chunk = cmemif->get_chunk_max_size();
for (size_t pos = 0; pos < len; pos += max_chunk)
cmemif->write_chunk(addr + pos, std::min(max_chunk, len - pos), (char*)bytes + pos);
}

8
fesvr/memif.h

@ -15,13 +15,17 @@ typedef reg_t addr_t;
class chunked_memif_t
{
size_t chunk_max_size = 0;
protected:
size_t chunk_align = 0;
chunked_memif_t(size_t chunk_max_sz, size_t chunk_al) : chunk_max_size(chunk_max_sz), chunk_align(chunk_al) {}
public:
virtual void read_chunk(addr_t taddr, size_t len, void* dst) = 0;
virtual void write_chunk(addr_t taddr, size_t len, const void* src) = 0;
virtual void clear_chunk(addr_t taddr, size_t len) = 0;
virtual size_t chunk_align() = 0;
virtual size_t chunk_max_size() = 0;
size_t get_chunk_max_size() const {return chunk_max_size;}
size_t get_chunk_align() const {return chunk_align;}
virtual endianness_t get_target_endianness() const {
return endianness_little;

6
fesvr/tsi.cc

@ -13,16 +13,12 @@ void tsi_t::host_thread(void *arg)
tsi->target->switch_to();
}
tsi_t::tsi_t(int argc, char** argv) : htif_t(argc, argv)
tsi_t::tsi_t(int argc, char** argv) : htif_t(argc, argv, /*chunk_max_size=*/1024, /*chunk_align=*/4)
{
target = context_t::current();
host.init(host_thread, this);
}
tsi_t::~tsi_t(void)
{
}
#define MSIP_BASE 0x2000000
// Interrupt core 0 to make it start executing the program in DRAM

4
fesvr/tsi.h

@ -19,7 +19,6 @@ class tsi_t : public htif_t
{
public:
tsi_t(int argc, char** argv);
virtual ~tsi_t();
bool data_available();
void send_word(uint32_t word);
@ -37,9 +36,6 @@ class tsi_t : public htif_t
void write_chunk(addr_t taddr, size_t nbytes, const void* src) override;
void switch_to_target();
size_t chunk_align() override { return 4; }
size_t chunk_max_size() override { return 1024; }
int get_ipi_addrs(addr_t *addrs);
private:

2
riscv/sim.cc

@ -48,7 +48,7 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
bool socket_enabled,
FILE *cmd_file, // needed for command line option --cmd
std::optional<unsigned long long> instruction_limit)
: htif_t(args),
: htif_t(args, /*chunk_max_size=*/8, /*chunk_align=*/8),
cfg(cfg),
mems(mems),
dtb_discovery(dtb_discovery),

2
riscv/sim.h

@ -158,8 +158,6 @@ private:
virtual void idle() override;
virtual void read_chunk(addr_t taddr, size_t len, void* dst) override;
virtual void write_chunk(addr_t taddr, size_t len, const void* src) override;
virtual size_t chunk_align() override { return 8; }
virtual size_t chunk_max_size() override { return 8; }
virtual endianness_t get_target_endianness() const override;
public:

Loading…
Cancel
Save