diff --git a/analysis/chartConfig b/analysis/chartConfig new file mode 100644 index 0000000..371879f --- /dev/null +++ b/analysis/chartConfig @@ -0,0 +1,23 @@ +outputFile chart.html +printTrace 1 +printAccumulateFlow 0 +eventType 0 0 1 0 + +group +trPath /etc/astra-sim/simulation/llama_hpn7_mix.tr +title tp2 +tp 4 +dp 1 +pp 1 +vpp 1 +dataRate 4000 +linkDelay 25 +sendLat 3000 +numLayer 4 +attnComp 275641 +mlpComp 440705 +switchNode 0 +switchNodePort 1 +switchNodePortNum 4 +actFlag 0 +nodeNum 4 diff --git a/analysis/print_chart.hpp b/analysis/print_chart.hpp new file mode 100644 index 0000000..9ea8945 --- /dev/null +++ b/analysis/print_chart.hpp @@ -0,0 +1,956 @@ +// +// Created by sx00007 on 2/19/25. +// + +#ifndef SIMAI_MASTER_PRINT_CHART_HPP +#define SIMAI_MASTER_PRINT_CHART_HPP + +#include "trace-format.h" +#include +#include +#include +#include +#include +#include +#include + +struct groupDataStruct{ + std::string trPath = "/etc/astra-sim/simulation/llama_hpn7_mix.tr"; + std::string title = "tp4"; + short tp = 4; + short dp = 1; + short pp = 1; + short vpp = 1; + short dataRate = 4000; //Gbps + short linkDelay = 25; //ns + short sendLat = 3000; //ns + short numLayer = 4; + u_int64_t attnComp = 275641; + u_int64_t mlpComp = 440705; + int switchNode = 4; + int switchNodePort = 1; + int switchNodeTotalRate = 16000; //Gbps + bool actFlag = false; + short nodeNum = 4; +}; +struct xy{ + uint64_t xTime; + uint64_t yCount = 0; +}; +struct dataPieStruct{ + uint64_t totalTime; + uint64_t compTime; + uint64_t commTime; + uint64_t dataTime; + uint64_t sendLatTime; + uint64_t linkDelay; + uint64_t bandDelay; + uint64_t forwardTime; + uint64_t backwardTime; + uint64_t igTime; + uint64_t wgTime; + uint64_t overlapTime; +}; +struct dataPacketMsg{ + uint64_t packetNum = 0; + uint64_t ackNum = 0; + std::vector data; +}; +struct dataPacketStr{ + std::string packetNum; + std::string ackNum; + std::string data; +}; + +std::string outputFile = "chart.html"; +std::ofstream outFile; + +short groupCount = -1; +std::vector groupDataVec; + +std::vector> timeToCount = {{},{}}; +std::vector dataVector; +std::vector> dataLineVec; +std::vector dataPieVec; +std::vector> compData = {}; +std::vector commData; +bool commFlag = false; + +dataPacketMsg dataPacket; +std::vector dataPacketStrVec; + +std::vector windowTime = {0, 0}; +short windowLength = 400; // 400ns +short windowCount = 10; // step = 400/10 = 40ns +std::vector> windowVec = {{},{}}; + +uint64_t totalTime = 0; +uint64_t tempTime = 0; +uint64_t beginTime = 0; +int maxValue = 0; +bool printTraceFlag = false; +bool printFlowFlag = false; +std::vector eventType = {0, 0, 1, 0}; + +uint64_t totalCount = 0; +uint64_t oneCount = 0; + +static void windowComp(ns3::TraceFormat &tr, short num); +static char l3ProtToChar(uint8_t p); + +static short initChart(std::string configPath) { + //init groupDataVec + std::ifstream conf; + conf.open(configPath); + if (!conf) { + print("Error opening configFile!\n"); + return 0; + } + while (!conf.eof()) { + std::string key; + conf >> key; + if (key.compare("outputFile") == 0) { + std::string v; + conf >> v; + outputFile = v; + } else if (key.compare("printTrace") == 0) { + short v; + conf >> v; + printTraceFlag = v; + } else if (key.compare("eventType") == 0) { + short v; + conf >> v; + eventType[0] = v; + conf >> v; + eventType[1] = v; + conf >> v; + eventType[2] = v; + conf >> v; + eventType[3] = v; + } else if (key.compare("printFlow") == 0) { + short v; + conf >> v; + printFlowFlag = v; + } else if (key.compare("group") == 0) { + groupDataStruct groupData; + groupDataVec.push_back(groupData); + groupCount++; + } else if (key.compare("trPath") == 0) { + std::string v; + conf >> v; + groupDataVec[groupCount].trPath = v; + } else if (key.compare("title") == 0) { + std::string v; + conf >> v; + groupDataVec[groupCount].title = v; + } else if (key.compare("tp") == 0) { + short v; + conf >> v; + groupDataVec[groupCount].tp = v; + } else if (key.compare("dp") == 0) { + short v; + conf >> v; + groupDataVec[groupCount].dp = v; + } else if (key.compare("pp") == 0) { + short v; + conf >> v; + groupDataVec[groupCount].pp = v; + } else if (key.compare("vpp") == 0) { + short v; + conf >> v; + groupDataVec[groupCount].vpp = v; + } else if (key.compare("dataRate") == 0) { + short v; + conf >> v; + groupDataVec[groupCount].dataRate = v; + } else if (key.compare("linkDelay") == 0) { + short v; + conf >> v; + groupDataVec[groupCount].linkDelay = v; + } else if (key.compare("sendLat") == 0) { + short v; + conf >> v; + groupDataVec[groupCount].sendLat = v; + } else if (key.compare("numLayer") == 0) { + short v; + conf >> v; + groupDataVec[groupCount].numLayer = v; + } else if (key.compare("attnComp") == 0) { + int v; + conf >> v; + groupDataVec[groupCount].attnComp = v; + } else if (key.compare("mlpComp") == 0) { + uint64_t v; + conf >> v; + groupDataVec[groupCount].mlpComp = v; + } else if (key.compare("switchNode") == 0) { + uint64_t v; + conf >> v; + groupDataVec[groupCount].switchNode = v; + } else if (key.compare("switchNodePort") == 0) { + int v; + conf >> v; + groupDataVec[groupCount].switchNodePort = v; + } else if (key.compare("switchNodePortNum") == 0) { + int v; + conf >> v; + groupDataVec[groupCount].switchNodeTotalRate = groupDataVec[groupCount].dataRate*v; + } else if (key.compare("actFlag") == 0) { + short v; + conf >> v; + groupDataVec[groupCount].actFlag = v; + } else if (key.compare("nodeNum") == 0) { + short v; + conf >> v; + groupDataVec[groupCount].nodeNum = v; + } + } + + short size = groupDataVec.size(); + outFile.open(outputFile); + if (!outFile) { + std::cerr << "无法打开文件以写入!" << std::endl; + return 0; + } + //init head + outFile << R"( + + + + + + + + + + )"; + + //init lineChart + for (short i = 0; i < size; ++i) { + outFile << "
\n"; + } + + //init pieChart + outFile << "
\n"; + for (short i = 0; i < size; ++i) { + outFile << "
\n"; + } + outFile << "
\n"; + //init barChart + outFile << R"( )"; + outFile << "
\n"; + + //init function + outFile << R"()"; + groupCount = -1; + return size; +} + +static std::string getTrPath() { + groupCount++; + dataVector.clear(); + tempTime = 0; + beginTime = 0; + for (auto& item : windowVec) { + item.clear(); + } + windowTime[0] = 0; + windowTime[1] = 0; + commFlag = false; + maxValue = 0; + for (auto& item : timeToCount) { + item.clear(); + } + std::vector dataLine; + dataLineVec.push_back(dataLine); + return groupDataVec[groupCount].trPath; +} + +static void dataCollection(ns3::TraceFormat &tr) { + if (printTraceFlag) { + switch (tr.l3Prot){ + case 0x6: + case 0x11: + printf("%lu n:%u %u:%u %u %s ecn:%x %08x %08x %hu %hu %c %u %lu %u %hu(%hu)", tr.time, tr.node, tr.intf, tr.qidx, tr.qlen, EventToStr((ns3::Event)tr.event), tr.ecn, tr.sip, tr.dip, tr.data.sport, tr.data.dport, l3ProtToChar(tr.l3Prot), tr.data.seq, tr.data.ts, tr.data.pg, tr.size, tr.data.payload); + break; + case 0xFC: // ACK + printf("%lu n:%u %u:%u %u %s ecn:%x %08x %08x %u %u %c 0x%02X %u %u %lu %hu", tr.time, tr.node, tr.intf, tr.qidx, tr.qlen, EventToStr((ns3::Event)tr.event), tr.ecn, tr.sip, tr.dip, tr.ack.sport, tr.ack.dport, l3ProtToChar(tr.l3Prot), tr.ack.flags, tr.ack.pg, tr.ack.seq, tr.ack.ts, tr.size); + break; + case 0xFD: // NACK + printf("%lu n:%u %u:%u %u %s ecn:%x %08x %08x %u %u %c 0x%02X %u %u %lu %hu", tr.time, tr.node, tr.intf, tr.qidx, tr.qlen, EventToStr((ns3::Event)tr.event), tr.ecn, tr.sip, tr.dip, tr.ack.sport, tr.ack.dport, l3ProtToChar(tr.l3Prot), tr.ack.flags, tr.ack.pg, tr.ack.seq, tr.ack.ts, tr.size); + break; + case 0xFE: // PFC + printf("%lu n:%u %u:%u %u %s ecn:%x %08x %08x %c %u %u %u %hu", tr.time, tr.node, tr.intf, tr.qidx, tr.qlen, EventToStr((ns3::Event)tr.event), tr.ecn, tr.sip, tr.dip, l3ProtToChar(tr.l3Prot), tr.pfc.time, tr.pfc.qlen, tr.pfc.qIndex, tr.size); + break; + case 0xFF: // CNP + printf("%lu n:%u %u:%u %u %s ecn:%x %08x %08x %c %u %u %u %u %u", tr.time, tr.node, tr.intf, tr.qidx, tr.qlen, EventToStr((ns3::Event)tr.event), tr.ecn, tr.sip, tr.dip, l3ProtToChar(tr.l3Prot), tr.cnp.fid, tr.cnp.qIndex, tr.cnp.ecnBits, tr.cnp.seq, tr.size); + break; + case 0x0: // QpAv + printf("%lu n:%u %u:%u %s %08x %08x %u %u", tr.time, tr.node, tr.intf, tr.qidx, EventToStr((ns3::Event)tr.event), tr.sip, tr.dip, tr.qp.sport, tr.qp.dport); + break; + default: + printf("%lu n:%u %u:%u %u %s ecn:%x %08x %08x %x %u", tr.time, tr.node, tr.intf, tr.qidx, tr.qlen, EventToStr((ns3::Event)tr.event), tr.ecn, tr.sip, tr.dip, tr.l3Prot, tr.size); + break; + } + printf("\n"); + } + if (tr.node != groupDataVec[groupCount].switchNode) { + return; + } + if (printFlowFlag && tr.event == 2) { + { + totalCount += tr.data.payload; + xy temp; + temp.xTime = tr.time; + temp.yCount = totalCount; + timeToCount[0].push_back(temp); + } + if (tr.intf == groupDataVec[groupCount].switchNodePort) { + oneCount += tr.data.payload; + xy temp; + temp.xTime = tr.time; + temp.yCount = oneCount; + timeToCount[1].push_back(temp); + } + } + if (!eventType[tr.event]) return; + if (tr.size== 60) { + dataPacket.ackNum++; + } else { + dataPacket.packetNum++; + } + if (dataPacket.data.size() < (tr.size/1000+1)) { + short temp = dataPacket.data.size(); + short length = tr.size/1000+1; + for (int i = temp; i < length; ++i) { + dataPacket.data.push_back(0); + } + } + if (maxValue < tr.size) { + maxValue = tr.size; + } + dataPacket.data[tr.size/1000]++; + if (!commFlag && beginTime!= 0 && tr.time - tempTime > 5000) { + commFlag = true; + commData.push_back(tempTime - beginTime + groupDataVec[groupCount].sendLat); + } + if (!printFlowFlag) { + if (beginTime == 0 && tr.size != 0) { + beginTime = tr.time; + } + + tempTime = tr.time; + + windowComp(tr, 0); + if (tr.intf != groupDataVec[groupCount].switchNodePort) { + return; + } + windowComp(tr, 1); + } +} + +static void setLineData() { + printf("dataLineVec:%d\n", dataLineVec.size()); + printf("timeToCount:%d\n", timeToCount[0].size()); + for (size_t ii = 0; ii < timeToCount.size(); ++ii) { + std::ostringstream data; + data << "["; + for (size_t i = 0; i < timeToCount[ii].size(); ++i) { + if (i != 0) { + data << ","; + } + data << "["; + data << std::fixed << std::setprecision(2) << timeToCount[ii][i].xTime; + data << ","; + data << std::fixed << std::setprecision(2) << timeToCount[ii][i].yCount; + data << "]"; + } + data << "]"; + dataLineVec[groupCount].push_back(data.str()); + } +} + +static void setBarData() { + dataPacketStr dataStr; + dataStr.ackNum = std::to_string(dataPacket.ackNum); + dataStr.packetNum = std::to_string(dataPacket.packetNum); + std::ostringstream data; + data << "["; + for (size_t i = 0; i < dataPacket.data.size(); ++i) { + if (i != 0) { + data << ","; + } + data << dataPacket.data[i]; + } + data << "]"; + dataStr.data = data.str(); + dataPacketStrVec.push_back(dataStr); +} + +static void setPieData() { + uint64_t attnComp = groupDataVec[groupCount].attnComp; + uint64_t mlpComp = groupDataVec[groupCount].mlpComp; + uint64_t numLayer = groupDataVec[groupCount].numLayer; + uint64_t tp = groupDataVec[groupCount].tp; + uint64_t compTime = numLayer * (attnComp + mlpComp); + dataPieStruct dataPie; + dataPie.totalTime = tempTime; + dataPie.compTime = 3 * compTime; + dataPie.commTime = dataPie.totalTime - dataPie.compTime; + dataPie.sendLatTime = (numLayer * 2 + 4) * (tp - 1) * 2 * groupDataVec[groupCount].sendLat; + dataPie.dataTime = dataPie.commTime - dataPie.sendLatTime; + dataPie.forwardTime = compTime; + dataPie.backwardTime = 2 * compTime; + dataPie.igTime = compTime; + dataPie.wgTime = compTime; + uint64_t mlpOverlap = std::min(commData[groupCount], mlpComp); + uint64_t attentionOverlap = std::min(commData[groupCount], attnComp); + dataPie.overlapTime = numLayer * (mlpOverlap + attentionOverlap); + dataPieVec.push_back(dataPie); +} + +static void setChartData() { + setLineData(); + setBarData(); + setPieData(); +} + +static void print2Line() { + short ii = -1; + for (auto &item: dataLineVec) { + ii++; + outFile << R"( + + )"; + } + + return; +} + +static void printPie() { + short i = -1; + for (auto& item : dataPieVec) { + i++; + std::string ii = std::to_string(i); + outFile << ")"; + } +} + +static void printBar() { + outFile << R"( + + )"; +} + +static void printChart() { + + print2Line(); +// for (short i = 0; i < groupDataVec.size(); ++i) { +// print2Line(); +// } + printPie(); + printBar(); + outFile << R"( + )"; + outFile.close(); + std::cout << "HTML 文件已生成,请打开 " << outputFile << " 查看效果。" << std::endl; +} + +static void windowComp(ns3::TraceFormat &tr, short num) { + if (windowVec[num].size() == 0) { + for (short i = 0; i < windowCount; ++i) { + windowVec[num].push_back(0); + } + } + short step = windowLength/windowCount; + uint64_t temp = windowTime[num] * step; + + if (temp > tr.time && temp - tr.time > step) return; + if (temp > tr.time && temp - tr.time <= step) { + windowVec[num][windowCount - 1] += tr.size; + return; + } + short oneLinkTime = maxValue*8 / groupDataVec[groupCount].dataRate + groupDataVec[groupCount].linkDelay; + if (tr.time >= temp && tr.time - temp > windowLength) { + for (short i = 0; i < windowCount; ++i) { + xy data; + data.xTime = windowTime[num] * step; + short j = 0; + for (auto &item : windowVec[num]) { + if (oneLinkTime > (j * step + step/2)) { + data.yCount = data.yCount + (j * step + step/2) * item / oneLinkTime; + } else { + data.yCount += item; + } + j++; + } + data.yCount = 8 * data.yCount/windowLength; + timeToCount[num].push_back(data); + windowVec[num][i] = 0; + windowTime[num]++; + } + xy data0; + data0.xTime = windowTime[num] * step; + data0.yCount = 0; + timeToCount[num].push_back(data0); + windowTime[num] = tr.time/step; + xy data; + data.xTime = windowTime[num] * step; + data.yCount = 0; + timeToCount[num].push_back(data); + windowTime[num]++; + windowVec[num][windowCount - 1] += tr.size; + } else if (tr.time >= temp) { + short count = (tr.time - step * windowTime[num]) / step + 1; + for (short i = 0; i < count; ++i) { + xy data; + data.xTime = windowTime[num] * step; + short j = 0; + for (auto &item : windowVec[num]) { + if (oneLinkTime > (j * step + step/2)) { + data.yCount = data.yCount + (j * step + step/2) * item / oneLinkTime; + } else { + data.yCount += item; + } + j++; + } + for (short j = 1; j < windowCount; ++j) { + windowVec[num][j - 1] = windowVec[num][j]; + } + windowVec[num][windowCount - 1] = 0; + data.yCount = 8 * data.yCount/windowLength; + windowTime[num]++; + timeToCount[num].push_back(data); + } + windowVec[num][windowCount - 1] = tr.size; + } +} + +static inline char l3ProtToChar(uint8_t p){ + switch (p){ + case 0x6: + return 'T'; + case 0x11: + return 'U'; + case 0xFC: // ACK + return 'A'; + case 0xFD: // NACK + return 'N'; + case 0xFE: // PFC + return 'P'; + case 0xFF: + return 'C'; + default: + return 'X'; + } +} + + + +#endif //SIMAI_MASTER_PRINT_CHART_HPP diff --git a/analysis/trace_reader.cpp b/analysis/trace_reader.cpp index 4536f22..d553b1e 100644 --- a/analysis/trace_reader.cpp +++ b/analysis/trace_reader.cpp @@ -4,43 +4,38 @@ #include #include "trace-format.h" #include "trace_filter.hpp" -#include "utils.hpp" #include "sim-setting.h" +#include "print_chart.hpp" using namespace ns3; using namespace std; int main(int argc, char** argv){ - if (argc != 2 && argc != 3){ - printf("Usage: ./trace_reader [filter_expr]\n"); - return 0; - } - FILE* file = fopen(argv[1], "r"); - TraceFilter f; - if (argc == 3){ - f.parse(argv[2]); - if (f.root == NULL){ - printf("Invalid filter\n"); - return 0; - } - } - //printf("filter: %s\n", f.str().c_str()); - - // first read SimSetting - SimSetting sim_setting; - sim_setting.Deserialize(file); - #if 0 - // print sim_setting - for (auto i : sim_setting.port_speed) - for (auto j : i.second) - printf("%u,%u:%lu\n", i.first, j.first, j.second); - #endif - - // read trace - TraceFormat tr; - while (tr.Deserialize(file) > 0){ - if (!f.test(tr)) - continue; - print_trace(tr); - } + if (argc != 2 && argc != 3){ + printf("Usage: ./trace_reader [filter_expr]\n"); + return 0; + } + short num = initChart(argv[1]); + if (num == 0) { + return 0; + } + for (int i = 0; i < num;) { + std::string strChar = getTrPath(); + FILE* file = fopen(strChar.c_str(), "r"); + if (file == NULL) { + print("Error opening tr_file!\n"); + continue; + } + SimSetting sim_setting; + sim_setting.Deserialize(file); + // read trace + TraceFormat tr; + while (tr.Deserialize(file) > 0){ + dataCollection(tr); + } + setChartData(); + i++; + } + printChart(); + return 0; }