Commit 9295c5e0 authored by shengjh's avatar shengjh 🇨🇳
Browse files

Work on function prepareRequestAndUnsched():change the unschedPkt to payload unschedPkt data part.

parent 274c0a83
......@@ -3,6 +3,7 @@
*_m.cc
*_sm.h
*_sm.cc
dctransport
/.settings
.vscode
......
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see http://www.gnu.org/licenses/.
//
package dctrans.simulations;
import inet.node.inet.Router;
import inet.networklayer.configurator.ipv4.Ipv4NetworkConfigurator;
import dctrans.node.HomaHost;
import ned.DatarateChannel;
network dcn
{
parameters:
xml topologyConfig = xmldoc("config.xml");
// This models NIC intrinsic delay
double edgeLinkDelay @unit(us) = default(0.0us);
// models the fabrciLinkDealy plus the intrinsic switching delay
double fabricLinkDelay @unit(us) = default(0.0us);
// Enables the cut-through switching wherever possible
//bool isFabricCutThrough = default(false);
// NOTE: always greater and equal to nicLinkSpeed
int fabricLinkSpeed @unit(Gbps);
// models the software trun around time, in the hosts, between the time
// ethFrame is received until the notification is received in software
// or when the pkt is send in software until it's received at the NIC.
//double hostSwTurnAroundTime @unit(us);
// when non-zero, it models the intrinsic fixed switching delay
// on the output ports of the routers
double switchFixDelay @unit(us);
// models NIC send think time in host nics.
double hostNicSxThinkTime @unit(us);
// must be greater than or equal to 1.0 (1.0 means full bisection bw)
double overSubFactor = default(1.0);
double realLoadFactor;
int nicLinkSpeed @unit(Gbps);
int numTors;
int numServersPerTor;
int numAggSwitches = (numServersPerTor * nicLinkSpeed) / (overSubFactor * fabricLinkSpeed);
int numHosts = numServersPerTor * numTors;
types:
channel FabricChannel extends ned.DatarateChannel
{
datarate = fabricLinkSpeed;
}
channel EdgeChannel extends DatarateChannel
{
datarate = nicLinkSpeed;
}
submodules:
aggRouter[numAggSwitches]: Router {
@display("i=abstract/router2;p=257,61");
**.promiscuous = true;
}
tor[numTors]: Router {
@display("i=abstract/router;p=257,157");
**.promiscuous = true;
}
host[numHosts]: HomaHost {
@display("i=device/server2;p=257,245");
hostConfig = xmldoc("config.xml", "/topologyConfig/hostConfig[@id=$MODULE_INDEX]");
//appConfig = xmldoc("config.xml", "/topologyConfig/hostConfig[@id=$PARENTMODULE_INDEX]/appConfig");
nicLinkSpeed = nicLinkSpeed;
fabricLinkSpeed = fabricLinkSpeed;
edgeLinkDelay = edgeLinkDelay;
fabricLinkDelay = fabricLinkDelay;
//app[*].hostSwTurnAroundTime = hostSwTurnAroundTime;
hostNicSxThinkTime = hostNicSxThinkTime;
switchFixDelay = switchFixDelay;
}
configurator: Ipv4NetworkConfigurator {
parameters:
config = xmldoc("config.xml", "/topologyConfig/IPv4Configurator/config");
@display("p=26,25");
}
connections allowunconnected:
for i=0..numTors-1, for j=0..numServersPerTor-1 {
tor[i].ethg$o++ --> EdgeChannel { delay = (edgeLinkDelay+switchFixDelay); } --> host[i * numServersPerTor + j].ethg$i++;
tor[i].ethg$i++ <-- EdgeChannel { delay = (edgeLinkDelay+hostNicSxThinkTime); } <-- host[i * numServersPerTor + j].ethg$o++;
}
for i=0..numAggSwitches-1, for j=0..numTors-1 {
aggRouter[i].ethg++ <--> FabricChannel { delay = (fabricLinkDelay+switchFixDelay); } <--> tor[j].ethg++;
}
}
[General]
network=dcn
*.host*.eth[0].typename = "LayeredEthernetInterface"
*.*.eth[*].macLayer.queue.typename = "EthernetPriorityQueue"
*.*.eth[*].macLayer.queue.buffer.typename = ""
*.host*.eth[0].macLayer.queue.numQueues = 8
*.host*.eth[0].macLayer.queue.queue[*].typename = "DropTailQueue"
*.*.ethernet.typename = "EthernetLayer"
*.*.ieee8021q.typename = "Ieee8021qLayer"
\ No newline at end of file
......@@ -561,8 +561,8 @@ WorkloadSynthesizer::processRcvdMsg(Packet* pk)
double
WorkloadSynthesizer::idealMsgEndToEndDelay(Ptr<const AppMessage> rcvdMsg)
{
int totalBytesTranmitted = 0;
inet::L3Address srcAddr = rcvdMsg->getSrcAddr();
int totalBytesTranmitted = 0;
ASSERT(srcAddr.getType() == inet::L3Address::AddressType::IPv4);
inet::L3Address destAddr = rcvdMsg->getDestAddr();
ASSERT(destAddr.getType() == inet::L3Address::AddressType::IPv4);
......
......@@ -12,8 +12,8 @@
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see http://www.gnu.org/licenses/.
//
package dctrans.node.homa;
import dctrans.node.base.LinkLayerNodeBase;
package dctrans.node;
import inet.node.base.LinkLayerNodeBase;
import inet.networklayer.contract.IRoutingTable;
import inet.networklayer.common.InterfaceTable;
import inet.networklayer.contract.INetworkLayer;
......@@ -30,43 +30,44 @@ import dctrans.transportlayer.ITransportScheme;
module HomaHost extends LinkLayerNodeBase
{
@display("i=device/pc2");
xml hostConfig;
int nicLinkSpeed @unit(Gbps);
int fabricLinkSpeed @unit(Gbps);
int numTrafficGeneratorApp = default(0);
// num of TCP apps. Specify the app types in INI file with
// tcpApp[0..1].typename="TCPEchoApp" syntax
//int numTcpApps = default(0);
// num of UDP apps. Specify the app types in INI file with
// udpApp[0..1].typename="UDPVideoStreamCli" syntax
//int numUdpApps = default(0);
bool hasTransportScheme = default(numTrafficGeneratorApp>0);
//bool hasTcp = default(numTcpApps>0);
//bool hasUdp = default((numUdpApps>0) || (numTrafficGeneratorApp>0));
// tcp implementation (e.g. ~TCP, ~TCP_lwIP, ~TCP_NSC) or ~TCPSpoof
//string tcpType = default(firstAvailable("TCP", "TCP_lwIP", "TCP_NSC", "TCP_None"));
//string udpType = default(firstAvailable("UDP","UDP_None"));
string transportSchemeType = default(firstAvailable("HomaTransport", "TransportSchemeNone"));
ipv4.arp.proxyArpInterfaces = default(""); // proxy arp is disabled on hosts by default
double edgeLinkDelay @unit(us);
double fabricLinkDelay @unit(us);
double hostSwTurnAroundTime @unit(us);
double hostNicSxThinkTime @unit(us);
double switchFixDelay @unit(us);
bool forwarding = default(true);
bool multicastForwarding = default(false);
*.forwarding = forwarding;
*.multicastForwarding = multicastForwarding;
bool hasUdp = default(firstAvailableOrEmpty("Udp") != "");
bool hasIpv4 = default(true);
parameters:
@display("i=device/pc2");
xml hostConfig;
int nicLinkSpeed @unit(Gbps);
int fabricLinkSpeed @unit(Gbps);
int numTrafficGeneratorApp = default(0);
// num of TCP apps. Specify the app types in INI file with
// tcpApp[0..1].typename="TCPEchoApp" syntax
//int numTcpApps = default(0);
// num of UDP apps. Specify the app types in INI file with
// udpApp[0..1].typename="UDPVideoStreamCli" syntax
//int numUdpApps = default(0);
bool hasTransportScheme = default(numTrafficGeneratorApp>0);
//bool hasTcp = default(numTcpApps>0);
//bool hasUdp = default((numUdpApps>0) || (numTrafficGeneratorApp>0));
// tcp implementation (e.g. ~TCP, ~TCP_lwIP, ~TCP_NSC) or ~TCPSpoof
//string tcpType = default(firstAvailable("TCP", "TCP_lwIP", "TCP_NSC", "TCP_None"));
//string udpType = default(firstAvailable("UDP","UDP_None"));
string transportSchemeType = default(firstAvailable("HomaTransport", "TransportSchemeNone"));
ipv4.arp.proxyArpInterfaces = default(""); // proxy arp is disabled on hosts by default
double edgeLinkDelay @unit(us);
double fabricLinkDelay @unit(us);
double hostSwTurnAroundTime @unit(us);
double hostNicSxThinkTime @unit(us);
double switchFixDelay @unit(us);
//copy from LinkLayerNodeBase.ned
bool forwarding = default(true);
bool multicastForwarding = default(false);
*.forwarding = forwarding;
*.multicastForwarding = multicastForwarding;
bool hasUdp = default(firstAvailableOrEmpty("Udp") != "");
bool hasIpv4 = default(true);
submodules:
......
//
// Copyright (C) 2020 OpenSim Ltd.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
package dctrans.node.base;
import inet.node.base.NodeBase;
import inet.common.MessageDispatcher;
import inet.common.packet.recorder.PcapRecorder;
import inet.linklayer.contract.IEthernetInterface;
import inet.linklayer.contract.ILoopbackInterface;
import inet.linklayer.contract.IPppInterface;
import inet.linklayer.contract.ITunnelInterface;
import inet.linklayer.contract.IVirtualInterface;
import inet.linklayer.contract.IWirelessInterface;
import inet.linklayer.ethernet.contract.IEthernetLayer;
import inet.linklayer.ieee8021q.IIeee8021qLayer;
import inet.networklayer.common.InterfaceTable;
module LinkLayerNodeBase extends NodeBase
{
parameters:
bool recordPcap = default(false);
int numPcapRecorders = default(recordPcap ? 1 : 0);
int numLoInterfaces = default(1);
int numWlanInterfaces = default(0);
int numEthInterfaces = default(0); // minimum number of ethernet interfaces
int numPppInterfaces = default(0); // minimum number of PPP interfaces
int numTunInterfaces = default(0);
int numVirtInterfaces = default(0);
pcapRecorder[*].pcapFile = default("results/" + fullPath() + ".pcap");
mobility.typename = default(numWlanInterfaces > 0 ? "StationaryMobility" : "");
*.interfaceTableModule = default(absPath(".interfaceTable"));
wlan[*].radio.antenna.mobilityModule = default("^.^.^.mobility");
@figure[linkLayer](type=rectangle; pos=250,456; size=1000,130; fillColor=#0000ff; lineColor=#808080; cornerRadius=5; fillOpacity=0.1);
@figure[linkLayer.title](type=text; pos=1245,461; anchor=ne; text="link layer");
@figure[interfaceLayer](type=rectangle; pos=250,606; size=1000,210; fillColor=#00ffff; lineColor=#808080; cornerRadius=5; fillOpacity=0.1);
@figure[interfaceLayer.title](type=text; pos=1245,611; anchor=ne; text="interface layer");
gates:
input radioIn[numWlanInterfaces] @directIn;
inout pppg[numPppInterfaces] @labels(PppFrame-conn) @allowUnconnected;
inout ethg[numEthInterfaces] @labels(EtherFrame-conn) @allowUnconnected;
submodules:
pcapRecorder[numPcapRecorders]: PcapRecorder {
parameters:
@display("p=125,640;is=s");
}
interfaceTable: InterfaceTable {
parameters:
@display("p=125,240;is=s");
}
li: MessageDispatcher {
parameters:
@display("p=750,596;b=1000,5,,,,1");
}
ethernet: <default("")> like IEthernetLayer if typename != "" {
parameters:
@display("p=375,526");
}
ieee8021q: <default("")> like IIeee8021qLayer if typename != "" {
parameters:
@display("p=525,526");
}
lo[numLoInterfaces]: <default("LoopbackInterface")> like ILoopbackInterface {
parameters:
@display("p=750,676,row,150");
}
// TODO move wlan interfaces after eth interfaces, but it changes IP address assignment and breaks examples/inet/configurator/complex.ini
wlan[numWlanInterfaces]: <default("Ieee80211Interface")> like IWirelessInterface {
parameters:
@display("p=375,766,row,150;q=queue");
}
ppp[sizeof(pppg)]: <default("PppInterface")> like IPppInterface {
parameters:
@display("p=300,676,row,150;q=txQueue");
}
eth[sizeof(ethg)]: <default("EthernetInterface")> like IEthernetInterface {
parameters:
@display("p=900,676,row,150;q=txQueue");
}
tun[numTunInterfaces]: <default("TunInterface")> like ITunnelInterface {
parameters:
@display("p=975,766,row,150;q=txQueue");
}
virt[numVirtInterfaces]: <default("VirtualInterface")> like IVirtualInterface {
parameters:
@display("p=975,766,row,150;q=txQueue");
}
connections allowunconnected:
ieee8021q.lowerLayerOut --> li.in++ if exists(ieee8021q);
li.out++ --> ieee8021q.lowerLayerIn if exists(ieee8021q);
ethernet.lowerLayerOut --> li.in++ if exists(ethernet);
li.out++ --> ethernet.lowerLayerIn if exists(ethernet);
for i=0..sizeof(radioIn)-1 {
radioIn[i] --> { @display("m=s"); } --> wlan[i].radioIn;
}
for i=0..sizeof(ethg)-1 {
ethg[i] <--> { @display("m=s"); } <--> eth[i].phys;
}
for i=0..sizeof(pppg)-1 {
pppg[i] <--> { @display("m=s"); } <--> ppp[i].phys;
}
for i=0..numLoInterfaces-1 {
li.out++ --> lo[i].upperLayerIn;
lo[i].upperLayerOut --> li.in++;
}
for i=0..sizeof(radioIn)-1 {
wlan[i].upperLayerOut --> li.in++;
wlan[i].upperLayerIn <-- li.out++;
}
for i=0..sizeof(ethg)-1 {
eth[i].upperLayerOut --> li.in++;
eth[i].upperLayerIn <-- li.out++;
}
for i=0..sizeof(pppg)-1 {
ppp[i].upperLayerOut --> li.in++;
ppp[i].upperLayerIn <-- li.out++;
}
for i=0..numTunInterfaces-1 {
tun[i].upperLayerOut --> li.in++;
tun[i].upperLayerIn <-- li.out++;
}
for i=0..numVirtInterfaces-1 {
virt[i].upperLayerOut --> li.in++;
virt[i].upperLayerIn <-- li.out++;
}
}
This diff is collapsed.
This diff is collapsed.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see http://www.gnu.org/licenses/.
//
import inet.common.TagBase;
cplusplus {{
#include "HomaTransport.h"
}}
class HomaTransport {
@existingClass;
}
class HomaTransport extends inet::TagBase
{
HomaTransport* homaTransport;
}
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see http://www.gnu.org/licenses/.
//
package dctrans.transportlayer.homa;
import dctrans.transportlayer.ITransportScheme;
//
// defines a credit based receiver side driven transport protocol
//
simple HomaTransport like ITransportScheme
{
parameters:
xml transportConfig = default(xml("<param/>"));
int nicLinkSpeed @unit(Gbps);
int rttBytes @unit(byte);
int grantMaxBytes @unit(byte) = default(1472B);
int maxOutstandingRecvBytes @unit(byte) = default(15000B);
int defaultReqBytes @unit(byte) = default(0B);
int defaultUnschedBytes @unit(byte) = default(9700B);
bool isRoundRobinScheduler = default(false);
int localPort = default(-1);
int destPort;
bool useUnschRateInScheduler = default(false);
int prioLevels; // All available prios
int adaptiveSchedPrioLevels; // Sched prio levels used for dynamic. scheduling
// This value must be smaller than schedPrioLevels
int prioResolverPrioLevels; // All available prio levels available for priority
// resolver
int numSendersToKeepGranted; // total number of most preffered senders that
// receiver concurrently sends grants for.
// priod intervals at which the transport fires signals that are
// collected by GlobalSignalListener.
double signalEmitPeriod @unit(s) = default(0.001s);
// If true, network traffic bytes from grant packets will be accounted in
// when computing CBF and unscheduled priority cutoff sizes.
bool accountForGrantTraffic = default(true);
// Coulde be any of PrioResolutionMode values in PriorityResolver.h
string unschedPrioResolutionMode;
// If unschedPrioResolutionMode is set to EXPLICIT,
// then this string defines the priority cutoff points of unsched
// bytes for the remaining message sizes. Example would be "100 1500 9000"
string explicitUnschedPrioCutoff = default("");
// Specifies for the unsched prio level, how many times prio p_i will be
// used comparing to p_i-1 (p_i is higher prio). Cutoff weight are used
// in PrioResolver class.
double unschedPrioUsageWeight = default(1.0);
// The kind of logic transport uses at sender for sending messages and pkts
string senderScheme = default("OBSERVE_PKT_PRIOS");
// Specifies that only first cbfCapMsgSize bytes of a message must
// be used in computing the cbf function. This value is supposed to be uint32_t
// type, but since NED don't support 'unsigned int',
// we enter integers in the string form.
string cbfCapMsgSize = default("0x100000000");
// This value is in bytes and determines that this number of last scheduled
// bytes of the message will be send at priority equal to unscheduled
// priorites. The default is 0 bytes.
string boostTailBytesPrio = default("0x0");
// If receiver inbound link is idle for longer than "linkCheckBytes /
// linkSpeed", while there are senders waiting for grants, we consider
// receiver bw is wasted. -1 is reserved to disable bw-waste detection
//with this mechanism.
int linkCheckBytes @unit(byte) = default(-1B);
// Only for simulation purpose, we allow the transport to be aware of
// workload type. The value must be similar to WorkloadSynthesizer
// workloadType.
string workloadType = default("");
@signal[msgsLeftToSend](type=long);
@signal[stabilitySignal](type=unsigned long);
@signal[bytesLeftToSend](type=long);
@signal[totalOutstandingBytes](type=long);
@signal[totalOutstandingBytes](type=long);
@singal[homaPktPrio*Signal](type=HomaPkt);
@signal[rxActiveTime](type=simtime_t);
@signal[higherRxSelfWasteTime](type=simtime_t);
@signal[lowerRxSelfWasteTime](type=simtime_t);
@signal[rxActiveBytes](type=long);
@signal[oversubscriptionTime](type=simtime_t);
@signal[oversubscriptionBytes](type=long);
@signal[sxActiveTime](type=simtime_t);
@signal[sxActiveBytes](type=long);
@signal[sxSchedPktDelay](type=simtime_t);
@signal[sxUnschedPktDelay](type=simtime_t);
@signal[activeSchedMesgs];
@statistic[msgsLeftToSend](title="num msgs left to send"; source=msgsLeftToSend; record=stats, histogram; interpolationmode=none);
@statistic[bytesLeftToSend](title="num total bytes left to send"; source=bytesLeftToSend; record=stats, histogram; interpolationmode=none);
@statistic[bytesNeedGrant](title="num total sched bytes left to send"; source=bytesNeedGrant; record=stats, histogram; interpolationmode=none);
@statistic[totalOutstandingBytes](title="total bytes in flight"; source=totalOutstandingBytes; record=stats, histogram; interpolationmode=none);
@statistic[outstandingGrantBytes](title="num total bytes left to send"; source=outstandingGrantBytes; record=stats, histogram; interpolationmode=none);
@statisticTemplate[pktPrioStats](title="Per pkt priority statistics"; record=stats(homaMsgSize), stats(homaPktBytes), stats(homaUnschedPktBytes), stats(homaGrantPktBytes); interpolationmode=none);
@statistic[rxActiveTime](title="Time periods receiver expects to get bytes"; source=rxActiveTime; record=stats, histogram; interpolationmode=none);
@statistic[rxActiveBytes](title="Bytes received during each active period"; source=rxActiveBytes; record=stats, histogram; interpolationmode=none);
@statistic[oversubscriptionTime](title="Time periods receiver has more senders than it grants"; source=oversubscriptionTime; record=stats, histogram; interpolationmode=none);
@statistic[oversubscriptionBytes](title="Bytes received during each oversubscription time"; source=oversubscriptionBytes; record=stats, histogram; interpolationmode=none);
@statistic[sxActiveTime](title="Time periods sender has bytes to send"; source=sxActiveTime; record=stats, histogram; interpolationmode=none);
@statistic[sxActiveBytes](title="Bytes sent during each active period"; source=sxActiveBytes; record=stats, histogram; interpolationmode=none);
@statistic[sxSchedPktDelay](title="Sender delays for sched pkts"; source=sxSchedPktDelay; record=stats, histogram; interpolationmode=none);
@statistic[sxUnschedPktDelay](title="Sender delays for unsched pkts"; source=sxUnschedPktDelay; record=stats, histogram; interpolationmode=none);
gates:
input appIn[] @labels(AppMessage/down);
input udpIn @labels(UDPControlInfo/up);
output appOut[] @labels(AppMessage/up);
output udpOut @labels(UDPControlInfo/down);
}
/*
* PriorityResolver.cc
*
* Created on: Jul 12, 2021
* Author: jhsheng
*/
#include "PriorityResolver.h"
PriorityResolver::PriorityResolver(HomaConfigDepot* homaConfig,
WorkloadEstimator* distEstimator)
: cdf(&distEstimator->cdfFromFile)
, cbf(&distEstimator->cbfFromFile)
, cbfLastCapBytes(&distEstimator->cbfLastCapBytesFromFile)
, remainSizeCbf(&distEstimator->remainSizeCbf)
, prioCutOffs()
, distEstimator(distEstimator)
, prioResMode()
, homaConfig(homaConfig)
{
distEstimator->getCbfFromCdf(distEstimator->cdfFromFile,
homaConfig->cbfCapMsgSize, homaConfig->boostTailBytesPrio);
distEstimator->getRemainSizeCdfCbf(distEstimator->cdfFromFile,
homaConfig->cbfCapMsgSize, homaConfig->boostTailBytesPrio);
prioResMode = strPrioModeToInt(homaConfig->unschedPrioResolutionMode);
setPrioCutOffs();
}
uint16_t
PriorityResolver::getMesgPrio(uint32_t msgSize)
{
size_t mid, high, low;
low = 0;
high = prioCutOffs.size() - 1;
while(low < high) {
mid = (high + low) / 2;
if (msgSize <= prioCutOffs.at(mid)) {
high = mid;
} else {
low = mid + 1;
}
}
return high;
}
std::vector<uint16_t>
PriorityResolver::getUnschedPktsPrio(const OutboundMessage* outbndMsg)
{