Victima: feature extension
Victima当前的缺陷
至少支持两级缓存, 不支持只设置L1缓存,但是支持设置L1缓存Passthrough。
目标
支持原生的L1缓存
测试环境
- 可运行机器 icarus0-4、hades0-1
- 代码 https://github.com/ACSA-PIM/Victima/tree/NDP_dev
- 运行测试脚本 https://github.com/ACSA-PIM/UniNDP-virtuoso/tree/master/test-test
运行
Victima容器环境依赖的配置与启动
选择 icarus3 机器, 使用Podman测试, 直接使用docker的Dockerfile
1 | FROM docker.io/kanell21/artifact_evaluation:victima |
依次执行build和run即可
1 | podman build -t victima . |
程序的编译
我们使用外部挂载目录来实现文件的共享(主要是便于vscode修改)
1 | # 下载需要的分支 |
测试与运行
- 待测试脚本位于
UniNDP-virtuoso/tree/master/test-test,~/UniNDP-virtuoso/test-test/run_ndp.sh只需运行25s - 最短的8min的例子的trace为
/staff/tubuxin/codes/Victima/traces_small/GraphBIG_BFS_amazon0302_30M.sift
1 | sniper=/root/Victima/sniper/run-sniper |
调试与分析
podman容器包装,加上sniper的多进程协同。使得GDB比较麻烦。还是采用从配置参数和关键输出两方面入手来理解代码逻辑
配置分析
实际运行指令输入了6个config文件。从sim.cfg寻找cache相关参数
1 | [perf_model/cache] |
在/staff/shaojiemike/test/Victima/src/Victima/sniper/config/UniNDP/configs/UniNDP_baseline_NDP_cuckoo.cfg中被找到。
??? bug “问题一: 设置 levels = 1 & passthrough = “false” 无法运行”
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Creating L1-I cache with 64 sets, 8-way associative, 64B blocksize
Initializing cache L 3
Creating L1-D cache with 64 sets, 8-way associative, 64B blocksize
[SNIPER] Internal exception: Segmentation fault. Access Address = 0x18
14355 139
inside nested try
inside try
0
[SNIPER] End
[SNIPER] Elapsed time: 2.07 seconds
------------------------------------------------------------
Segmentation fault. Access Address = 0x18
Backtrace:
cache_cntlr.cc:ParametricDramDirectoryMSI::CacheCntlr::setPrevCacheCntlrs:348
memory_manager.cc:ParametricDramDirectoryMSI::MemoryManager::MemoryManager:715 (discriminator 1)
memory_manager_base.cc:MemoryManagerBase::createMMU:18
core.cc:Core::Core:100
vector.tcc:void std::vector<Core*, std::allocator<Core*> >::emplace_back<Core*>:94 (discriminator 3)
simulator.cc:Simulator::start:158 (discriminator 15)
simulator.h:Simulator::getSingleton:46
??:??:0
??:_start:?
------------------------------------------------------------
可见运行时直接越界了。
分析报错函数调用栈
hl_lines 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// simulator.cc:Simulator::start:158 (discriminator 15)
m_core_manager = new CoreManager();
// core.cc:Core::Core:100
m_memory_manager = MemoryManagerBase::createMMU(
Sim()->getCfg()->getString("caching_protocol/type"),
this, m_network, m_shmem_perf_model);
// memory_manager_base.cc:MemoryManagerBase::createMMU:18
MemoryManagerBase*
MemoryManagerBase::createMMU(String protocol_type,
Core* core, Network* network, ShmemPerfModel* shmem_perf_model)
{
CachingProtocol_t caching_protocol = parseProtocolType(protocol_type);
switch (caching_protocol)
{
case PARAMETRIC_DRAM_DIRECTORY_MSI:
return new ParametricDramDirectoryMSI::MemoryManager(core, network, shmem_perf_model);
case FAST_NEHALEM:
return new FastNehalem::MemoryManager(core, network, shmem_perf_model);
default:
LOG_PRINT_ERROR("Unsupported Caching Protocol (%u)", caching_protocol);
return NULL;
}
}
// memory_manager.cc:ParametricDramDirectoryMSI::MemoryManager::MemoryManager:715 (discriminator 1)
m_cache_cntlrs[MemComponent::L2_CACHE]->setPrevCacheCntlrs(prev_cache_cntlrs);
// cache_cntlr.cc:ParametricDramDirectoryMSI::CacheCntlr::setPrevCacheCntlrs:348
void
CacheCntlr::setPrevCacheCntlrs(CacheCntlrList& prev_cache_cntlrs)
{
/* Append our prev_caches list to the master one (only master nodes) */
for(CacheCntlrList::iterator it = prev_cache_cntlrs.begin(); it != prev_cache_cntlrs.end(); it++)
if ((*it)->isMasterCache())
m_master->m_prev_cache_cntlrs.push_back(*it);
LOG_ASSERT_ERROR(m_master->m_prev_cache_cntlrs.size() <= MAX_NUM_PREVCACHES, "shared locations vector too small, increase MAX_NUM_PREVCACHES to at least %u", m_master->m_prev_cache_cntlrs.size());
}
跟踪了解相关变量的类型和定义。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 变量创建其一 cache_cntlr.cc: CacheCntlr::CacheCntlr():118
m_master = new CacheMasterCntlr(name, core_id, cache_params.outstanding_misses);
// 函数定义
CacheMasterCntlr(String name, core_id_t core_id, UInt32 outstanding_misses)
: m_cache(NULL)
, m_prefetcher(NULL)
, m_dram_cntlr(NULL)
, m_dram_outstanding_writebacks(NULL)
, m_l1_mshr(name + ".mshr", core_id, outstanding_misses)
, m_next_level_read_bandwidth(name + ".next_read", core_id)
, m_evicting_address(0)
, m_evicting_buf(NULL)
, m_atds()
, m_prefetch_list()
, m_prefetch_next(SubsecondTime::Zero())
{}
// m_prev_cache_cntlrs的位置,
class CacheMasterCntlr
{
private:
CacheCntlrList m_prev_cache_cntlrs;
...
}
问题: `m_prev_cache_cntlrs`不需要初始化吗?
1
2
3
4
5
6
7
class CacheCntlrList : public std::vector<CacheCntlr*>
{
public:
PrevCacheIndex find(core_id_t core_id, MemComponent::component_t mem_component);
};
就是`std::vector<CacheCntlr*>`,应该是不需要初始化的。
体会
感觉Victima设计初期就没考虑只有一层cache的情况。导致各处都不支持,野指针和越界到处都是。程序的完备性有待提升。
参考文献
[^1]: Victima github
[^2]: Podman Non-Root “Error setting up pivot dir”
[^4]: Rootless Podman and NFS
Victima: feature extension
http://icarus.shaojiemike.top/2024/04/17/Work/software/simulator/Victima/
