simulation round, s/he has to allocate and free a dynar and use it as argument
to this function. The former SD_simulate (double how_long) now returns void.
+ Virtual Machines
+ - Allow multicore VMs, along with the correct sharing computations
+
MSG
- The netzone are now available from the MSG API.
The old names still work, but are now deprecated.
launch_computation_worker(vm0);
while(MSG_get_clock()<100) {
- if (atask != NULL)
- XBT_INFO("aTask remaining duration: %g", MSG_task_get_flops_amount(atask));
- MSG_process_sleep(1);
+ if (atask != NULL)
+ XBT_INFO("aTask remaining duration: %g", MSG_task_get_flops_amount(atask));
+ MSG_process_sleep(1);
}
MSG_process_sleep(10000);
return 1;
}
-static void launch_master(msg_host_t host)
-{
- const char *pr_name = "master_";
- char **argv = xbt_new(char *, 2);
- argv[0] = xbt_strdup(pr_name);
- argv[1] = NULL;
-
- MSG_process_create_with_arguments(pr_name, master_main, NULL, host, 1, argv);
-}
-
int main(int argc, char *argv[]){
MSG_init(&argc, argv);
xbt_assert(argc == 2);
MSG_create_environment(argv[1]);
- launch_master(MSG_host_by_name("Fafard"));
+ MSG_process_create("master_", master_main, NULL, MSG_host_by_name("Fafard"));
int res = MSG_main();
XBT_INFO("Bye (simulation time %g)", MSG_get_clock());
/* Host 1 */
XBT_INFO("Creating and starting two VMs");
- msg_vm_t vm_host1 = MSG_vm_create(host1, "vm_host1", 2048, 10, 50);
+ msg_vm_t vm_host1 = MSG_vm_create(host1, "vm_host1", 1, 2048, 10, 50);
MSG_vm_start(vm_host1);
- msg_vm_t vm_host3 = MSG_vm_create(host3, "vm_host3", 2048, 10, 50);
+ msg_vm_t vm_host3 = MSG_vm_create(host3, "vm_host3", 1, 2048, 10, 50);
MSG_vm_start(vm_host3);
XBT_INFO("Create two tasks on Host1: one inside a VM, the other directly on the host");
// TODO add VDI later
XBT_PUBLIC(msg_vm_t) MSG_vm_create_core(msg_host_t location, const char *name);
+XBT_PUBLIC(msg_vm_t) MSG_vm_create_multicore(msg_host_t pm, const char* name, int coreAmount);
XBT_PUBLIC(msg_vm_t)
-MSG_vm_create(msg_host_t ind_pm, const char* name, int ramsize, int mig_netspeed, int dp_intensity);
+MSG_vm_create(msg_host_t ind_pm, const char* name, int coreAmount, int ramsize, int mig_netspeed, int dp_intensity);
XBT_PUBLIC(void) MSG_vm_destroy(msg_vm_t vm);
{
public:
- explicit VirtualMachine(const char* name, s4u::Host* hostPm);
+ explicit VirtualMachine(const char* name, s4u::Host* hostPm, int coreAmount);
// No copy/move
VirtualMachine(VirtualMachine const&) = delete;
MSG_vm_set_bound(vm, bound);
}
-JNIEXPORT void JNICALL Java_org_simgrid_msg_VM_create(JNIEnv* env, jobject jvm, jobject jhost, jstring jname,
- jint jramsize, jint jmig_netspeed, jint jdp_intensity)
+JNIEXPORT void JNICALL Java_org_simgrid_msg_VM_create(JNIEnv* env, jobject jVm, jobject jHost, jstring jname,
+ jint coreAmount, jint jramsize, jint jmig_netspeed,
+ jint jdp_intensity)
{
- msg_host_t host = jhost_get_native(env, jhost);
+ msg_host_t host = jhost_get_native(env, jHost);
const char* name = env->GetStringUTFChars(jname, 0);
- msg_vm_t vm = MSG_vm_create(host, name, static_cast<int>(jramsize), static_cast<int>(jmig_netspeed),
- static_cast<int>(jdp_intensity));
+ msg_vm_t vm = MSG_vm_create(host, name, static_cast<int>(coreAmount), static_cast<int>(jramsize),
+ static_cast<int>(jmig_netspeed), static_cast<int>(jdp_intensity));
env->ReleaseStringUTFChars(jname, name);
- jvm_bind(env, jvm, vm);
- jvm = env->NewWeakGlobalRef(jvm);
+ jvm_bind(env, jVm, vm);
+ jVm = env->NewWeakGlobalRef(jVm);
// We use the extension level of the host, even if that's somehow disturbing
- vm->extension_set(JAVA_HOST_LEVEL, (void*)jvm);
+ vm->extension_set(JAVA_HOST_LEVEL, (void*)jVm);
}
JNIEXPORT jobjectArray JNICALL Java_org_simgrid_msg_VM_all(JNIEnv* env, jclass cls_arg)
JNIEXPORT void JNICALL Java_org_simgrid_msg_VM_setBound(JNIEnv* env, jobject jvm, jdouble bound);
JNIEXPORT void JNICALL Java_org_simgrid_msg_VM_create(JNIEnv* env, jobject jvm, jobject jhost, jstring jname,
- jint jramsize, jint dprate, jint mig_netspeed);
+ jint coreAmount, jint jramsize, jint dprate, jint mig_netspeed);
JNIEXPORT jobject JNICALL Java_org_simgrid_msg_VM_getVMByName(JNIEnv* env, jclass cls, jstring jname);
JNIEXPORT void JNICALL Java_org_simgrid_msg_VM_nativeFinalize(JNIEnv* env, jobject jvm);
JNIEXPORT void JNICALL Java_org_simgrid_msg_VM_start(JNIEnv* env, jobject jvm);
// No need to declare a new bind variable: we use the one inherited from the super class Host
private Host currentHost;
+ private int coreAmount = 1;
/** Create a `basic' VM (i.e. 1GB of RAM, other values are not taken into account). */
public VM(Host host, String name) {
- this(host,name,1024, 0, 0);
+ this(host,name, /*coreAmount*/1, 1024, 0, 0);
+ }
+
+ public VM(Host host, String name, int coreAmount) {
+ this(host,name, coreAmount, 1024, 0, 0);
+ }
+ public VM(Host host, String name, int ramSize, int migNetSpeed, int dpIntensity){
+ this(host, name, /*coreAmount*/1, ramSize, migNetSpeed, dpIntensity);
}
/**
* @param migNetSpeed (network bandwith allocated for migrations in MB/s, if you don't know put zero ;))
* @param dpIntensity (dirty page percentage according to migNetSpeed, [0-100], if you don't know put zero ;))
*/
- public VM(Host host, String name, int ramSize, int migNetSpeed, int dpIntensity){
+ public VM(Host host, String name, int coreAmount, int ramSize, int migNetSpeed, int dpIntensity){
super();
super.name = name;
this.currentHost = host;
- create(host, name, ramSize, migNetSpeed, dpIntensity);
+ this.coreAmount = coreAmount;
+ create(host, name, coreAmount, ramSize, migNetSpeed, dpIntensity);
}
/** Retrieve the list of all existing VMs */
* @param migNetSpeed (network bandwith allocated for migrations in MB/s, if you don't know put zero ;))
* @param dpIntensity (dirty page intensity, a percentage of migNetSpeed [0-100], if you don't know put zero ;))
*/
- private native void create(Host host, String name, int ramSize, int migNetSpeed, int dpIntensity);
+ private native void create(Host host, String name, int coreAmount, int ramSize, int migNetSpeed, int dpIntensity);
/**
* @ingroup msg_VMs*
* @param pm Physical machine that will host the VM
* @param name Must be unique
+ * @param coreAmount Must be >= 1
* @param ramsize [TODO]
* @param mig_netspeed Amount of Mbyte/s allocated to the migration (cannot be larger than net_cap). Use 0 if unsure.
* @param dp_intensity Dirty page percentage according to migNetSpeed, [0-100]. Use 0 if unsure.
*/
-msg_vm_t MSG_vm_create(msg_host_t pm, const char* name, int ramsize, int mig_netspeed, int dp_intensity)
+msg_vm_t MSG_vm_create(msg_host_t pm, const char* name, int coreAmount, int ramsize, int mig_netspeed, int dp_intensity)
{
simgrid::vm::VmHostExt::ensureVmExtInstalled();
double host_speed = MSG_host_get_speed(pm);
double update_speed = (static_cast<double>(dp_intensity)/100) * mig_netspeed;
- msg_vm_t vm = MSG_vm_create_core(pm, name);
+ msg_vm_t vm = MSG_vm_create_multicore(pm, name, coreAmount);
s_vm_params_t params;
memset(¶ms, 0, sizeof(params));
params.ramsize = static_cast<sg_size_t>(ramsize) * 1024 * 1024;
return vm;
}
-/** @brief Create a new VM object. The VM is not yet started. The resource of the VM is allocated upon MSG_vm_start().
+/** @brief Create a new VM object with the default parameters
* @ingroup msg_VMs*
*
* A VM is treated as a host. The name of the VM must be unique among all hosts.
xbt_assert(sg_host_by_name(name) == nullptr,
"Cannot create a VM named %s: this name is already used by an host or a VM", name);
- return new simgrid::s4u::VirtualMachine(name, pm);
+ return new simgrid::s4u::VirtualMachine(name, pm, 1);
+}
+/** @brief Create a new VM object with the default parameters, but with a specified amount of cores
+ * @ingroup msg_VMs*
+ *
+ * A VM is treated as a host. The name of the VM must be unique among all hosts.
+ */
+msg_vm_t MSG_vm_create_multicore(msg_host_t pm, const char* name, int coreAmount)
+{
+ xbt_assert(sg_host_by_name(name) == nullptr,
+ "Cannot create a VM named %s: this name is already used by an host or a VM", name);
+
+ return new simgrid::s4u::VirtualMachine(name, pm, coreAmount);
}
/** @brief Destroy a VM. Destroy the VM object from the simulation.
std::deque<s4u::VirtualMachine*> VirtualMachineImpl::allVms_;
/* In the real world, processes on the guest operating system will be somewhat degraded due to virtualization overhead.
- * The total CPU share these processes get is smaller than that of the VM process gets on a host operating system. */
+ * The total CPU share these processes get is smaller than that of the VM process gets on a host operating system.
+ * FIXME: add a configuration flag for this
+ */
// const double virt_overhead = 0.95;
const double virt_overhead = 1;
*
* Equation 1 was solved in the physical machine layer.
* Equation 2 is solved in the virtual machine layer (here).
- * X1 must be passed to the virtual machine laye as a constraint value.
+ * X1 must be passed to the virtual machine layer as a constraint value.
**/
/* iterate for all virtual machines */
surf::Cpu* cpu = ws_vm->pimpl_cpu;
xbt_assert(cpu, "cpu-less host");
- double solved_value = ws_vm->pimpl_vm_->action_->getVariable()->value;
+ double solved_value = ws_vm->pimpl_vm_->action_->getVariable()
+ ->value; // this is X1 in comment above, what this VM got in the sharing on the PM
XBT_DEBUG("assign %f to vm %s @ pm %s", solved_value, ws_vm->cname(), ws_vm->pimpl_vm_->getPm()->cname());
// TODO: check lmm_update_constraint_bound() works fine instead of the below manual substitution.
}
/* 2. Calculate resource share at the virtual machine layer. */
- adjustWeightOfDummyCpuActions();
+ ignoreEmptyVmInPmLMM();
- /* 3. Ready. Get the next occuring event */
+ /* 3. Ready. Get the next occurring event */
return surf_cpu_model_vm->nextOccuringEvent(now);
}
* Resource *
************/
-VirtualMachineImpl::VirtualMachineImpl(simgrid::s4u::VirtualMachine* piface, simgrid::s4u::Host* host_PM)
- : HostImpl(piface), hostPM_(host_PM)
+VirtualMachineImpl::VirtualMachineImpl(simgrid::s4u::VirtualMachine* piface, simgrid::s4u::Host* host_PM,
+ int coreAmount)
+ : HostImpl(piface), hostPM_(host_PM), coreAmount_(coreAmount)
{
/* Register this VM to the list of all VMs */
allVms_.push_back(piface);
/* We create cpu_action corresponding to a VM process on the host operating system. */
/* TODO: we have to periodically input GUESTOS_NOISE to the system? how ? */
- action_ = host_PM->pimpl_cpu->execution_start(0);
+ action_ = host_PM->pimpl_cpu->execution_start(0, coreAmount);
/* Initialize the VM parameters */
params_.ramsize = 0;
/* Update vcpu's action for the new pm */
/* create a cpu action bound to the pm model at the destination. */
- surf::CpuAction* new_cpu_action = static_cast<surf::CpuAction*>(destination->pimpl_cpu->execution_start(0));
+ surf::CpuAction* new_cpu_action =
+ static_cast<surf::CpuAction*>(destination->pimpl_cpu->execution_start(0, this->coreAmount_));
if (action_->getRemainsNoUpdate() > 0)
XBT_CRITICAL("FIXME: need copy the state(?), %f", action_->getRemainsNoUpdate());
friend simgrid::s4u::VirtualMachine;
public:
- explicit VirtualMachineImpl(s4u::VirtualMachine* piface, s4u::Host* host);
+ explicit VirtualMachineImpl(s4u::VirtualMachine * piface, s4u::Host * host, int coreAmount);
~VirtualMachineImpl();
/** @brief Suspend the VM */
private:
s_vm_params_t params_;
+ int coreAmount_;
protected:
e_surf_vm_state_t vmState_ = SURF_VM_STATE_CREATED;
*/
class VMModel : public surf::HostModel {
public:
- void adjustWeightOfDummyCpuActions() override{};
+ void ignoreEmptyVmInPmLMM() override{};
double nextOccuringEvent(double now) override;
void updateActionsState(double /*now*/, double /*delta*/) override{};
namespace simgrid {
namespace s4u {
-VirtualMachine::VirtualMachine(const char* name, s4u::Host* pm)
- : Host(name), pimpl_vm_(new vm::VirtualMachineImpl(this, pm))
+VirtualMachine::VirtualMachine(const char* name, s4u::Host* pm, int coreAmount)
+ : Host(name), pimpl_vm_(new vm::VirtualMachineImpl(this, pm, coreAmount))
{
XBT_DEBUG("Create VM %s", name);
* constraint (capacity) of the VM in the PM layer. If the VM does not have any
* active task, the dummy CPU action must be deactivated, so that the VM does
* not get any CPU share in the PM layer. */
-void HostModel::adjustWeightOfDummyCpuActions()
+void HostModel::ignoreEmptyVmInPmLMM()
{
/* iterate for all virtual machines */
for (s4u::VirtualMachine* ws_vm : vm::VirtualMachineImpl::allVms_) {
ws_vm->pimpl_vm_->action_->setPriority(1);
} else {
- /* no task exits on this VM */
+ /* no task exist on this VM */
XBT_DEBUG("set the weight of the dummy CPU action on PM to 0");
ws_vm->pimpl_vm_->action_->setPriority(0);
public:
HostModel() : Model() {}
- virtual void adjustWeightOfDummyCpuActions();
+ virtual void ignoreEmptyVmInPmLMM();
virtual Action* executeParallelTask(int host_nb, sg_host_t* host_list, double* flops_amount, double* bytes_amount,
double rate);
};
while ((var = lmm_get_var_from_cnst(model()->getMaxminSystem(), constraint(), &elem))) {
CpuCas01Action* action = static_cast<CpuCas01Action*>(lmm_variable_id(var));
- lmm_update_variable_bound(model()->getMaxminSystem(), action->getVariable(), speed_.scale * speed_.peak);
+ lmm_update_variable_bound(model()->getMaxminSystem(), action->getVariable(),
+ action->requestedCore() * speed_.scale * speed_.peak);
}
Cpu::onSpeedChange();
}
}
+/** @brief Start a new execution on this CPU lasting @size flops and using one core */
CpuAction *CpuCas01::execution_start(double size)
{
return new CpuCas01Action(model(), size, isOff(), speed_.scale * speed_.peak, constraint());
}
+CpuAction* CpuCas01::execution_start(double size, int requestedCores)
+{
+ return new CpuCas01Action(model(), size, isOff(), speed_.scale * speed_.peak, constraint(), requestedCores);
+}
CpuAction *CpuCas01::sleep(double duration)
{
/**********
* Action *
**********/
-
-CpuCas01Action::CpuCas01Action(Model *model, double cost, bool failed, double speed, lmm_constraint_t constraint)
- : CpuAction(model, cost, failed, lmm_variable_new(model->getMaxminSystem(), this, 1.0, speed, 1))
+CpuCas01Action::CpuCas01Action(Model* model, double cost, bool failed, double speed, lmm_constraint_t constraint,
+ int requestedCore)
+ : CpuAction(model, cost, failed, lmm_variable_new(model->getMaxminSystem(), this, 1.0, speed, 1))
+ , requestedCore_(requestedCore)
{
if (model->getUpdateMechanism() == UM_LAZY) {
indexHeap_ = -1;
lmm_expand(model->getMaxminSystem(), constraint, getVariable(), 1.0);
}
+CpuCas01Action::CpuCas01Action(Model* model, double cost, bool failed, double speed, lmm_constraint_t constraint)
+ : CpuCas01Action(model, cost, failed, speed, constraint, 1)
+{
+}
+
+int CpuCas01Action::requestedCore()
+{
+ return requestedCore_;
+}
+
CpuCas01Action::~CpuCas01Action()=default;
}
~CpuCas01() override;
void apply_event(tmgr_trace_event_t event, double value) override;
CpuAction *execution_start(double size) override;
+ CpuAction* execution_start(double size, int requestedCore) override;
CpuAction *sleep(double duration) override;
bool isUsed() override;
friend CpuAction *CpuCas01::execution_start(double size);
friend CpuAction *CpuCas01::sleep(double duration);
public:
+ CpuCas01Action(Model* model, double cost, bool failed, double speed, lmm_constraint_t constraint, int coreAmount);
CpuCas01Action(Model *model, double cost, bool failed, double speed, lmm_constraint_t constraint);
~CpuCas01Action() override;
+ int requestedCore();
+
+private:
+ int requestedCore_ = 1;
};
}
*/
virtual simgrid::surf::Action *execution_start(double size)=0;
+ /**
+ * @brief Execute some quantity of computation on more than one core
+ *
+ * @param size The value of the processing amount (in flop) needed to process
+ * @param requestedCores The desired amount of cores. Must be >= 1
+ * @return The CpuAction corresponding to the processing
+ */
+ virtual simgrid::surf::Action* execution_start(double size, int requestedCores)
+ {
+ THROW_UNIMPLEMENTED;
+ return nullptr;
+ }
+
/**
* @brief Make a process sleep for duration (in seconds)
*
namespace surf {
double HostCLM03Model::nextOccuringEvent(double now){
- adjustWeightOfDummyCpuActions();
+ ignoreEmptyVmInPmLMM();
double min_by_cpu = surf_cpu_model_pm->nextOccuringEvent(now);
double min_by_net = surf_network_model->nextOccuringEventIsIdempotent() ? surf_network_model->nextOccuringEvent(now) : -1;
msg_vm_t vm0;
msg_process_t daemon;
- vm0 = MSG_vm_create(jupiter, "vm0", 2048, 125, dpRate);
+ vm0 = MSG_vm_create(jupiter, "vm0", 1, 2048, 125, dpRate);
MSG_vm_start(vm0);
argvF = xbt_new(char*, 2);