我一直在为gem5缓存实现一个自定义替换策略。我遵循DuelingRP的模型,包括参数的初始化。但是,当我尝试用scon构建gem5时,它在链接阶段失败,出现以下错误。
/usr/bin/ld: build/X86/python/_m5/param_TSelRP.o: in function void pybind11::cpp_function::initialize<pybind11::cpp_function::initialize<gem5::replacement_policy::TSel*, gem5::TSelRPParams, , pybind11::name, pybind11::is_method, pybind11::sibling>(gem5::replacement_policy::TSel* (gem5::TSelRPParams::*)() const, pybind11::name const&, pybind11::is_method const&, pybind11::sibling const&)::{lambda(gem5::TSelRPParams const*)#1}, gem5::replacement_policy::TSel*, gem5::TSelRPParams const*, pybind11::name, pybind11::is_method, pybind11::sibling>(pybind11::cpp_function::initialize<gem5::replacement_policy::TSel*, gem5::TSelRPParams, , pybind11::name, pybind11::is_method, pybind11::sibling>(gem5::replacement_policy::TSel* (gem5::TSelRPParams::*)() const, pybind11::name const&, pybind11::is_method const&, pybind11::sibling const&)::{lambda(gem5::TSelRPParams const*)#1}&&, gem5::replacement_policy::TSel* (*)(gem5::TSelRPParams const*), pybind11::name const&, pybind11::is_method const&, pybind11::sibling const&)':
/.../ext/pybind11/include/pybind11/pybind11.h:210: undefined reference to gem5::TSelRPParams::create() const'
下面列出了类定义的相关代码。
tsel_rp.cc
/** TSel class constructor */
TSel::TSel(const Params &p)
: Base(p), replPolicyA(p.replacement_policy_a),
indexPolicyA(p.index_policy_a),
replPolicyB(p.replacement_policy_b),
indexPolicyB(p.index_policy_b)
{
}
tsel_rp.hh
#ifndef __MEM_CACHE_REPLACEMENT_POLICIES_TSEL_RP_HH__
#define __MEM_CACHE_REPLACEMENT_POLICIES_TSEL_RP_HH__
#include <cstddef>
#include <cstdint>
#include <memory>
#include "base/compiler.hh"
#include "base/sat_counter.hh"
#include "base/statistics.hh"
#include "mem/cache/cache.hh"
#include "mem/cache/replacement_policies/base.hh"
#include "mem/cache/tags/indexing_policies/base.hh"
namespace gem5
{
struct TSelRPParams;
GEM5_DEPRECATED_NAMESPACE(ReplacementPolicy, replacement_policy);
namespace replacement_policy
{
class TSel : public Base
{
protected:
/**
* TSel-specific implementation of replacement data. Contains all
* sub-replacement policies' replacement data.
*/
struct TSelReplData : ReplacementData
{
std::shared_ptr<ReplacementData> replDataA;
std::shared_ptr<ReplacementData> replDataB;
/** Default constructor. Initialize sub-replacement data. */
TSelReplData(const std::shared_ptr<ReplacementData>& repl_data_a,
const std::shared_ptr<ReplacementData>& repl_data_b)
: ReplacementData(), replDataA(repl_data_a),
replDataB(repl_data_b)
{
}
};
/** Sub-replacement policy used in this multiple container. */
Base* const replPolicyA;
/** Sub-indexing policy used in this multiple container. */
BaseIndexingPolicy* const indexPolicyA;
/** Sub-replacement policy used in this multiple container. */
Base* const replPolicyB;
/** Sub-indexing policy used in this multiple container. */
BaseIndexingPolicy* const indexPolicyB;
/** List of saturating counters to use for each set in the cache */
std::vector<SatCounter16> SCTRs;
/** Pointer to the actual implementation of the cache */
Cache *cache;
private:
bool isAddressInEntries(const Addr addr,
const ReplacementCandidates& entries);
void updateAuxiliaryDirectories(const Addr addr, uint8_t costq);
SatCounter16 getCounter(const Addr addr);
public:
// This follows the model of the Dueling Replacement Policy
PARAMS(TSelRP);
TSel(const Params &p);
~TSel() = default;
void invalidate(const std::shared_ptr<ReplacementData>& replacement_data) override;
void touch(const std::shared_ptr<ReplacementData>& replacement_data, const PacketPtr pkt) override;
void reset(const std::shared_ptr<ReplacementData>& replacement_data) const override;
ReplaceableEntry* getVictim(const ReplacementCandidates& candidates, Addr addr) override;
std::shared_ptr<ReplacementData> instantiateEntry() override;
};
} // namespace replacement_policy
} // namespace gem5
#endif // __MEM_CACHE_REPLACEMENT_POLICIES_TSEL_RP_HH__
mem/缓存/替换策略/SConscript
SimObject('ReplacementPolicies.py', sim_objects=[
'BaseReplacementPolicy', 'DuelingRP' ... 'TSelRP'])
Source('dueling_rp.cc')
Source('tsel_rp.cc')
/mem/cache/replacement_policies/ReplacementPolicies.py
class BaseReplacementPolicy(SimObject):
type = 'BaseReplacementPolicy'
abstract = True
cxx_class = 'gem5::replacement_policy::Base'
cxx_header = "mem/cache/replacement_policies/base.hh"
class DuelingRP(BaseReplacementPolicy):
type = 'DuelingRP'
cxx_class = 'gem5::replacement_policy::Dueling'
cxx_header = "mem/cache/replacement_policies/dueling_rp.hh"
constituency_size = Param.Unsigned(
"The size of a region containing one sample")
team_size = Param.Unsigned(
"Number of entries in a sampling set that belong to a team")
replacement_policy_a = Param.BaseReplacementPolicy(
"Sub-replacement policy A")
replacement_policy_b = Param.BaseReplacementPolicy(
"Sub-replacement policy B")
class TSelRP(BaseReplacementPolicy):
type = 'TSelRP'
cxx_class = 'gem5::replacement_policy::TSel'
cxx_header = "mem/cache/replacement_policies/tsel_rp.hh"
# Auxiliary Indexing Policies
index_policy_a = Param.BaseIndexingPolicy(
"Auxiliary indexing policy A")
index_policy_b = Param.BaseIndexingPolicy(
"Auxiliary indexing policy B")
# Replacement Policies for TSel
replacement_policy_a = Param.BaseReplacementPolicy(
"Sub-replacement policy A")
replacement_policy_b = Param.BaseReplacementPolicy(
"Sub-replacement policy B")
# Number of counter bits
num_counter_bits = Param.Int(3, "Number of counter bits")
相关的params文件,包括具有DummyShunt实现的create的DummyShunt文件,也已正确生成。
param_TSelRP.cc
/**
* DO NOT EDIT THIS FILE!
* File automatically generated by
* build_tools/sim_object_param_struct_cc.py:62
*/
#include "pybind11/pybind11.h"
#include "pybind11/stl.h"
#include <type_traits>
#include "base/compiler.hh"
#include "params/TSelRP.hh"
#include "sim/init.hh"
#include "sim/sim_object.hh"
#include "mem/cache/replacement_policies/tsel_rp.hh"
#include "mem/cache/tags/indexing_policies/base.hh"
#include "mem/cache/tags/indexing_policies/base.hh"
#include "base/types.hh"
#include "mem/cache/replacement_policies/base.hh"
#include "mem/cache/replacement_policies/base.hh"
namespace py = pybind11;
namespace gem5
{
static void
module_init(py::module_ &m_internal)
{
py::module_ m = m_internal.def_submodule("param_TSelRP");
py::class_<TSelRPParams, BaseReplacementPolicyParams, std::unique_ptr<TSelRPParams, py::nodelete>>(m, "TSelRPParams")
.def(py::init<>())
.def("create", &TSelRPParams::create)
.def_readwrite("index_policy_a", &TSelRPParams::index_policy_a)
.def_readwrite("index_policy_b", &TSelRPParams::index_policy_b)
.def_readwrite("num_counter_bits", &TSelRPParams::num_counter_bits)
.def_readwrite("replacement_policy_a", &TSelRPParams::replacement_policy_a)
.def_readwrite("replacement_policy_b", &TSelRPParams::replacement_policy_b)
;
py::class_<gem5::replacement_policy::TSel, gem5::replacement_policy::Base, std::unique_ptr<gem5::replacement_policy::TSel, py::nodelete>>(m, "gem5_COLONS_replacement_policy_COLONS_TSel")
;
}
static EmbeddedPyBind embed_obj("TSelRP", module_init, "BaseReplacementPolicy");
} // namespace gem5
namespace gem5
{
namespace
{
class DummyTSelRPParamsClass
{
public:
gem5::replacement_policy::TSel *create() const;
};
template <class CxxClass, class Enable=void>
class DummyTSelRPShunt;
template <class CxxClass>
class DummyTSelRPShunt<CxxClass, std::enable_if_t<
std::is_constructible_v<CxxClass,
const TSelRPParams &>>>
{
public:
using Params = TSelRPParams;
static gem5::replacement_policy::TSel *
create(const Params &p)
{
return new CxxClass(p);
}
};
template <class CxxClass>
class DummyTSelRPShunt<CxxClass, std::enable_if_t<
!std::is_constructible_v<CxxClass,
const TSelRPParams &>>>
{
public:
using Params = DummyTSelRPParamsClass;
static gem5::replacement_policy::TSel *
create(const Params &p)
{
return nullptr;
}
};
} // anonymous namespace
[[maybe_unused]] gem5::replacement_policy::TSel *
DummyTSelRPShunt<gem5::replacement_policy::TSel>::Params::create() const
{
return DummyTSelRPShunt<gem5::replacement_policy::TSel>::
create(*this);
}
} // namespace gem5
和TSelRP.hh
/**
* DO NOT EDIT THIS FILE!
* File automatically generated by
* build_tools/sim_object_param_struct_hh.py:50
*/
#ifndef __PARAMS__TSelRP__
#define __PARAMS__TSelRP__
namespace gem5 {
namespace replacement_policy {
class TSel;
} // namespace replacement_policy
} // namespace gem5
#include <cstddef>
#include "params/BaseIndexingPolicy.hh"
#include <cstddef>
#include "params/BaseIndexingPolicy.hh"
#include <cstddef>
#include "base/types.hh"
#include <cstddef>
#include "params/BaseReplacementPolicy.hh"
#include <cstddef>
#include "params/BaseReplacementPolicy.hh"
#include "params/BaseReplacementPolicy.hh"
namespace gem5
{
struct TSelRPParams
: public BaseReplacementPolicyParams
{
gem5::replacement_policy::TSel * create() const;
gem5::BaseIndexingPolicy * index_policy_a;
gem5::BaseIndexingPolicy * index_policy_b;
int num_counter_bits;
gem5::replacement_policy::Base * replacement_policy_a;
gem5::replacement_policy::Base * replacement_policy_b;
};
} // namespace gem5
#endif // __PARAMS__TSelRP__
我尝试从头开始重建Gem5,但是在链接阶段它仍然失败。对此错误的其他引用可以找到这里和这里。然而,这些其他错误似乎是由于相关的params文件不是自动生成的结果。
任何帮助都将不胜感激。
发布于 2022-06-08 18:57:59
问题是我们重载了gem5替换策略base.cc touch()函数,而没有在替换策略中显式实现原始函数。也就是说,我们只执行:
void touch(const std::shared_ptr<ReplacementData>& replacement_data, const PacketPtr pkt) override;
而不是:
void touch(const std::shared_ptr<ReplacementData>& replacement_data) override;
我们认为这导致编译器不承认我们的替换策略是“适当的”替换策略。不确定为什么会抛出与参数相关的特定错误,并将进一步调查。
https://stackoverflow.com/questions/72502976
复制相似问题