本文介绍消息事件产生器MessageEventGenerator及其派生类OneToEachMessageGeneratorOneFromEachMessageGeneratorMessageBurstGenerator

1. 配置文件

消息事件产生器MessageEventGenerator根据参数产生消息创建事件,进而创建消息。消息事件产生器类型对应于消息产生类型。使用方法如下:

# 消息事件产生器类型
Events1.class = MessageEventGenerator

# 消息创建间隔,每隔(25,35)秒产生一个消息,间隔随机从(25,35)产生
Events1.interval = 25,35

# 消息大小,产生消息的大小随机从(min, max)取得,单位是字节
Events1.size = 500k,1M

# Senderaddress range, 值得注意的是,包含下限但不包含上限,即[0, 126)
Events1.hosts = 0,126
# receiver address range,同样,包含下限但不包含上限。若没有设置,被视为与hosts同
Events1.tohosts = 0, 126

# 消息名称的前缀(Message ID prefix),用于标识不同的generator产生的消息
Events1.prefix = M

# 创建消息的时间范围[min, max],默认情况是[0, Scenario.endTime],即整个仿真期间都可以创建消息
Events1.time = 500, 1000

2. 消息事件产生器类型

MessageEventGenerator派生出3种新的消息产生器,即OneToEachMessageGeneratorOneFromEachMessageGeneratorMessageBurstGenerator。The ONE目前共支持4种消息产生方式,其类图如下:

img

注:以下内容有些繁琐,建议直接阅读仿真报告《消息创建报告CreatedMessagesReport》,更直观。

2.1 MessageEventGenerator

产生的消息是一对一的,以上述配置文件的参数为例,在第32s(随机从25~35选取)产生一个消息,消息大小为800kB(随机从500k~1M选取),源节点是5(随机从0~126选取),目的节点是100(随机从0~126选取)。将消息放入节点5的缓冲区。

2.2 OneToEachMessageGenerator

产生的消息是一对多的(Creates one message from source node/nodes to all destination nodes)。值得注意的是tohosts必须指定。从字面上理解,在每隔interval,消息的源节点从hosts随机选取一个,创建多个消息,其目的节点涵盖所有tohosts。但从源码看并非如此,仿真结果也验证了这一点,消息的源节点从hosts随机选取一个,并不是在单个interval,同时创建多个消息给tohosts,而是各个消息之间的间隔是(25,35)。实际上,用OneToEachMessageGenerator产生消息,整个仿真期间最多产生tohosts个消息。源代码为证:

//OneToEachMessageGenerator.java
public ExternalEvent nextEvent() {
    int responseSize = 0; // no responses requested
    int from;
    int to;

    from = drawHostAddress(hostRange);
    to = this.toIds.remove(0);

    if (to == from) { // skip self 
        if (this.toIds.size() == 0) { // oops, no more from addresses 
            this.nextEventsTime = Double.MAX_VALUE;
            return new ExternalEvent(Double.MAX_VALUE);
        } else {
            to = this.toIds.remove(0);
        }
    }

    if (this.toIds.size() == 0) {
        this.nextEventsTime = Double.MAX_VALUE; // no messages left
    } else {
        this.nextEventsTime += drawNextEventTimeDiff();
    }

    MessageCreateEvent mce = new MessageCreateEvent(from, to, getID(), drawMessageSize(), responseSize, this.nextEventsTime);

    return mce;
}

2.3 OneFromEachMessageGenerator

产生的消息是多对一的(Creates one message from every source node to one of the destination nodes)。值得注意的是tohosts必须指定。从字面上理解,在每隔intervalhosts每个节点产生一个消息给某个目的节点(从tohosts随机选择)。但从源码看并非如此,仿真结果也验证了这一点,每个间隔interval,从剩下的源节点随机选取一个,目的节点从tohosts随机选一个。可见,用OneFromEachMessageGenerator产生消息,整个仿真期间最多产生hosts个消息。源代码为证:

//OneFromEachMessageGenerator.java
public ExternalEvent nextEvent() {
    int responseSize = 0; // no responses requested 
    int from;
    int to;

    from = this.fromIds.remove(0);
    to = drawToAddress(toHostRange, -1);

    if (to == from) { //skip self
        if (this.fromIds.size() == 0) { //no more from addresses
            this.nextEventsTime = Double.MAX_VALUE;
            return new ExternalEvent(Double.MAX_VALUE);
        } else {
            from = this.fromIds.remove(0);
        }
    }

    if (this.fromIds.size() == 0) {
        this.nextEventsTime = Double.MAX_VALUE; //no messages left
    } else {
        this.nextEventsTime += drawNextEventTimeDiff();
    }

    MessageCreateEvent mce = new MessageCreateEvent(from, to, getID(), drawMessageSize(), responseSize, this.nextEventsTime);

    return mce;
}

2.4 MessageBurstGenerator

MessageBurstGenerator产生的消息是多对多。每个interval,每个源节点hosts为每个目的节点tohosts产生一个新消息。直接看源码注释吧:

Creates bursts of messages where every source node creates a new message to every destination node on every interval.

MessageBurstGenerator的nextEvent源代码如下:

//MessageBurstGenerator.java
public ExternalEvent nextEvent() {
    int responseSize = 0; // no responses requested
    int msgSize;
    int interval;
    int from;
    int to;
    boolean nextBurst = false;

    from = this.hostRange[0] + nextFromOffset;
    to = this.toHostRange[0] + nextToOffset;

    if (to == from) {
        to = this.toHostRange[0] + (++nextToOffset);
    }

    msgSize = drawMessageSize();
    MessageCreateEvent mce = new MessageCreateEvent(from, to, getID(), msgSize, responseSize, this.nextEventsTime);

    //其实类似于双重循环, for each host; for each tohosts; 产生一个消息创建事件
    if (to < this.toHostRange[1] - 1) {
        this.nextToOffset++;
    } else {
        if (from < this.hostRange[1] - 1) {
            this.nextFromOffset++;
            this.nextToOffset = 0;
        } else {
            nextBurst = true;
        }
    }

    if (this.hostRange[0] + nextFromOffset == this.toHostRange[0] + nextToOffset) { //to and from would be same for next event 
        nextToOffset++;
        if (nextToOffset >= toHostRange[1]) { 
            nextBurst = true;
        }
    }

    //到下一个hosts
    if (nextBurst) {
        interval = drawNextEventTimeDiff();
        this.nextEventsTime += interval;
        this.nextFromOffset = 0;
        this.nextToOffset = 0;
    }

    if (this.msgTime != null && this.nextEventsTime > this.msgTime[1]) { //next event would be later than the end time
        this.nextEventsTime = Double.MAX_VALUE;
    }

    return mce;
}
本文系Spark & Shine原创,转载需注明出处本文最近一次修改时间 2022-03-27 15:22

results matching ""

    No results matching ""