1%{ @file sn_get_node_tput_from_tput.m
2 % @brief Computes average throughputs at
nodes from station throughputs
4 % @author LINE Development Team
8 % @brief Computes average throughputs at
nodes from station throughputs
11 % This function calculates the average throughput at each node in steady-state
12 % from the station throughputs and node-level routing matrix.
16 % TNn = sn_get_node_tput_from_tput(sn, TN, TH)
17 % TNn = sn_get_node_tput_from_tput(sn, TN, TH, ANn)
22 % <tr><th>Name<th>Description
23 % <tr><td>sn<td>Network structure
24 % <tr><td>TN<td>Average throughputs at stations
25 % <tr><td>TH<td>Throughput handles
26 % <tr><td>ANn<td>(Optional) Average arrival rates at
nodes; computed
if missing
31 % <tr><th>Name<th>Description
32 % <tr><td>TNn<td>Average throughputs at
nodes
35function TNn=sn_get_node_tput_from_tput(sn, TN, TH, ANn)
41 ANn = sn_get_node_arvr_from_tput(sn, TN, TH);
45if ~isempty(TH) && ~isempty(TN)
48 inchain = sn.inchain{c};
49 refstat = sn.refstat(c);
51 if sn.nodetype(ind) ~= NodeType.Source
52 switch sn.nodetype(ind)
54 % For cache
nodes, use actual hit/miss ratios
if available
55 % instead of
nodevisits which don
't account for cache behavior
56 hitclass = sn.nodeparam{ind}.hitclass;
57 missclass = sn.nodeparam{ind}.missclass;
58 totalTput = sum(TN(refstat,inchain));
60 % Check if actual hit/miss probabilities are available in nodeparam
61 if isfield(sn.nodeparam{ind}, 'actualhitprob
') && ~isempty(sn.nodeparam{ind}.actualhitprob)
62 % Use actual hit/miss probabilities from solver result
63 actualHitProb = sn.nodeparam{ind}.actualhitprob;
64 actualMissProb = sn.nodeparam{ind}.actualmissprob;
65 % Delayed hits (retrieval system) depart as the hit
66 % class, so the hit-class throughput is (true hit +
67 % delayed hit) * total arrival. Zero for plain caches.
68 if isfield(sn.nodeparam{ind}, 'actualdelayedhitprob
') && ~isempty(sn.nodeparam{ind}.actualdelayedhitprob)
69 actualDelayedHitProb = sn.nodeparam{ind}.actualdelayedhitprob;
71 actualDelayedHitProb = zeros(size(actualHitProb));
74 % see _kb/04-networkstruct.md (api/sn/*.m derived-field helpers) for rationale
75 for origClass = 1:length(hitclass)
76 % see _kb/04-networkstruct.md (api/sn/*.m derived-field helpers) for rationale
78 arvTput = ANn(ind, origClass);
79 elseif any(origClass == inchain)
80 arvTput = TN(refstat, origClass);
82 arvTput = 0; % read class outside this chain
84 if hitclass(origClass) == r && origClass <= length(actualHitProb) && ~isnan(actualHitProb(origClass))
85 % This is a hit class - use hit probability
86 % (true hits plus delayed hits)
88 if origClass <= length(actualDelayedHitProb) && ~isnan(actualDelayedHitProb(origClass))
89 dh = actualDelayedHitProb(origClass);
91 TNn(ind, r) = TNn(ind, r) + arvTput * (actualHitProb(origClass) + dh);
92 elseif missclass(origClass) == r && origClass <= length(actualMissProb) && ~isnan(actualMissProb(origClass))
93 % This is a miss class - use miss probability
94 TNn(ind, r) = TNn(ind, r) + arvTput * actualMissProb(origClass);
98 % Fallback to nodevisits-based calculation
99 if any(find(r==hitclass)) || any(find(r==missclass))
100 TNn(ind, r) = (sn.nodevisits{c}(ind,r) / sum(sn.visits{c}(sn.stationToStateful(refstat),inchain))) * totalTput;
109 % First, copy station throughputs directly to station nodes
112 ind = sn.stationToNode(ist);
113 TNn(ind,:) = TN(ist,:);
118 inchain = sn.inchain{c};
120 anystateful = find(sn.visits{c}(:,r));
121 if ~isempty(anystateful)
122 if sn.nodetype(ind) ~= NodeType.Sink && sn.nodetype(ind) ~= NodeType.Join
125 switch sn.nodetype(ind)
127 ist = sn.nodeToStation(ind);
128 TNn(ind, s) = TN(ist,s);
131 TNn(ind, s) = TNn(ind, s) + ANn(ind, r) * sn.rtnodes((ind-1)*R+r, (jnd-1)*R+s);
134 % For station nodes, throughput is already set from TN
135 % Only compute for non-station nodes (like ClassSwitch, Router)
136 % Note: nodeToStation returns NaN for non-station nodes, so use ~(>0) check
137 if ~(sn.nodeToStation(ind) > 0)
138 TNn(ind, s) = TNn(ind, s) + ANn(ind, r) * sn.rtnodes((ind-1)*R+r, (jnd-1)*R+s);
143 elseif sn.nodetype(ind) == NodeType.Join
146 if sn.nodetype(ind) ~= NodeType.Source
147 TNn(ind, s) = TNn(ind, s) + ANn(ind, r) * sn.rtnodes((ind-1)*R+r, (jnd-1)*R+s);
149 ist = sn.nodeToStation(ind);
150 TNn(ind, s) = TN(ist,s);