Question:
拷贝数据粒度问题:
Min:Page (Mitosis)
Mixture:针对Function每次拷贝完整instance。针对memory等,则按页拷贝。
Instance:每次拷贝一个instance,例如一个FunctionInstance
Module :每次拷贝一个module
Max: .wasm / .so (Faasm)
Plan:先用Tcp做测试,做好模块化,方便后面改quic。先做No COW
Running Node:
1.在TableInstance、FunctionInstance等.cpp文件,增加反序列化初始化函数(原始只有一个从Mod数据初始化的函数)。
1 2 3 4 5 6
| instantiate(Module &Mod) instantiate(String obj) instantiate_userfault() instantiate_userfault(String obj, fault_ref)
|
2.在module.cpp,增加一个instantiate函数的重载,进行remote初始化runtime。此instantiate函数,调用第1条中的反序列化初始化函数进行初始化
Memory Node:
3.设计一个“镜像类”,用于”镜像”和”储存”序列化后的runtime数据。并设计一个network方法,用于监听网络请求,根据请求发送相应的runtime数据
1 2 3 4 5 6
| std::vector<FunctionInstance *> FuncInsts; std::vector<TableInstance *> TabInsts; std::vector<MemoryInstance *> MemInsts; std::vector<GlobalInstance *> GlobInsts; std::vector<ElementInstance *> ElemInsts; std::vector<DataInstance *> DataInsts;
|
No COW
一次性拷贝:Store,Conf。之后直接执行
COW
只拷贝Conf,拷贝Store的大小。然后进行userfault初始化。之后执行,遇到fault,则利用handle线程处理
WASMEdge分析
1.wasm相关数据存储在Store中
2.一个wasm程序由多个modules组成
启动流程:
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 41 42 43 44 45 46 47 48 49 50 51 52
| const auto InputPath = std::filesystem::absolute(SoName.value());
VM::VM VM(Conf); -> unsafeInitVM(); -> unsafeLoadBuiltInHosts(); 加载 BuiltInModInsts unsafeRegisterBuiltInHosts(); 登记 ExecutorEngine.registerModule -> instantiate(StoreMgr, Mod, Name)
VM.loadWasm(InputPath.u8string()); -> LoaderEngine.parseModule(Path) -> FMgr.setPath(FilePath) -> module.loadModule() VM.validate(); -> ValidatorEngine.validate(*Mod.get()) VM.instantiate(); -> ExecutorEngine.instantiateModule(StoreRef, *Mod.get()) -> instantiate(StoreMgr, Mod) -> 初始化 ActiveModInst
WasiMod->getEnv().init( Dir.value(), InputPath.filename() Args.value(), Env.value());
std::vector<ValVariant> FuncArgs;
VM.asyncExecute(FuncName, FuncArgs, FuncArgTypes); -> ExecutorEngine.invoke(*FuncInst, Params, ParamTypes) -> runFunction(StackMgr, FuncInst, Params) FuncInst是一个指针,指向Stack中的函数位置
|
Remote Migration steps
Step1: VM init
这一步,需要从远端拷贝Conf。然后返序列化Conf进行初始化。
1 2 3 4 5 6 7 8 9 10 11 12
| VM(const Configure &Conf): Conf(Conf) Stage(VMStage::Inited), LoaderEngine(Conf, &Executor::Executor::Intrinsics), ValidatorEngine(Conf), ExecutorEngine(Conf, &Stat), Store(std::make_unique<Runtime::StoreManager>()), StoreRef(*Store.get()) { unsafeLoadBuiltInHosts(); unsafeRegisterBuiltInHosts(); }
|
Stpe2: Module & Stack init
将以下三步:VM.loadWasm() -> VM.validate() -> VM.instantiate()
由本地读取文件从而实例化module,改为云端获取。需要拷贝很多个细小的变量,一个都不能漏掉
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| VM.loadWasm(InputPath.u8string());
VM.validate();
VM.instantiate();
|
No COW:需要从远端拷贝module,直接反序列化
COW:先假初始化,遇到了page fault再从远端拷贝
参考:
module本地加载实现:lib/loader/ast/module.cpp
module定义: include/ast/module.h
StoreMgr、moduleInstance初始化:lib/executor/instantiate/module.cpp
lib/executor/instantiate/data.cpp
moduleInstance实例化
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
| std::unique_ptr<Runtime::Instance::ModuleInstance> ModInst;
ModInst = std::make_unique<Runtime::Instance::ModuleInstance>(Name.value());
ModInst->addFuncType(FuncType);
AST::ImportSection &ImportSec = Mod.getImportSection(); instantiate(StoreMgr, *ModInst, ImportSec)
const AST::FunctionSection &FuncSec = Mod.getFunctionSection(); const AST::CodeSection &CodeSec = Mod.getCodeSection(); instantiate(*ModInst, FuncSec, CodeSec);
AST::TableSection &TabSec = Mod.getTableSection(); instantiate(*ModInst, TabSec);
const AST::MemorySection &MemSec = Mod.getMemorySection(); instantiate(*ModInst, MemSec);
const AST::ExportSection &ExportSec = Mod.getExportSection(); instantiate(*ModInst, ExportSec);
instantiate(StackMgr, *ModInst, ElemSec)
instantiate(StackMgr, *ModInst, DataSec)
|
https://github.com/bytecodealliance/wasm-micro-runtime/blob/main/doc/memory_tune.md

https://juejin.cn/post/6844904062148689933