Skip to content

Commit 7a1bd1a

Browse files
authored
Merge pull request #510 from ddiproietto/improve_split_v2
Optimize RunModuleSplit() and reduce TLS usage
2 parents 38538f8 + d98495b commit 7a1bd1a

2 files changed

Lines changed: 20 additions & 17 deletions

File tree

core/module.cc

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -592,32 +592,33 @@ void Module::RunSplit(const gate_idx_t *out_gates,
592592
gate_idx_t pending[bess::PacketBatch::kMaxBurst];
593593
bess::PacketBatch batches[bess::PacketBatch::kMaxBurst];
594594

595-
bess::PacketBatch *splits = ctx.splits();
595+
bess::PacketBatch **splits = ctx.splits();
596596

597-
/* phase 1: collect unique ogates into pending[] */
597+
// phase 1: collect unique ogates into pending[] and add packets to local
598+
// batches, using splits to remember the association between an ogate and a
599+
// local batch
598600
for (int i = 0; i < cnt; i++) {
599601
bess::PacketBatch *batch;
600602
gate_idx_t ogate;
601603

602604
ogate = out_gates[i];
603-
batch = &splits[ogate];
605+
batch = splits[ogate];
606+
if (!batch) {
607+
batch = splits[ogate] = &batches[num_pending];
608+
batch->clear();
609+
pending[num_pending] = ogate;
610+
num_pending++;
611+
}
604612

605613
batch->add(*(p_pkt++));
606-
607-
pending[num_pending] = ogate;
608-
num_pending += (batch->cnt() == 1);
609614
}
610615

611-
/* phase 2: move batches to local stack, since it may be reentrant */
616+
// phase 2: clear splits, since it may be reentrant.
612617
for (int i = 0; i < num_pending; i++) {
613-
bess::PacketBatch *batch;
614-
615-
batch = &splits[pending[i]];
616-
batches[i].Copy(batch);
617-
batch->clear();
618+
splits[pending[i]] = nullptr;
618619
}
619620

620-
/* phase 3: fire */
621+
// phase 3: fire
621622
for (int i = 0; i < num_pending; i++)
622623
RunChooseModule(pending[i], &batches[i]);
623624
}

core/worker.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,7 @@ class Worker {
9191
gate_idx_t current_igate() const { return current_igate_; }
9292
void set_current_igate(gate_idx_t idx) { current_igate_ = idx; }
9393

94-
/* better be the last field. it's huge */
95-
bess::PacketBatch *splits() { return splits_; }
94+
bess::PacketBatch **splits() { return splits_; }
9695

9796
private:
9897
volatile worker_status_t status_;
@@ -115,8 +114,11 @@ class Worker {
115114
* Modules should use get_igate() for access */
116115
gate_idx_t current_igate_;
117116

118-
/* better be the last field. it's huge */
119-
bess::PacketBatch splits_[MAX_GATES + 1];
117+
// For each possible output gate contains a pointer to a batch, or nullptr,
118+
// if no batch has been associated with the output gate yet.
119+
//
120+
// This should be the last field, since it's huge.
121+
bess::PacketBatch *splits_[MAX_GATES + 1];
120122
};
121123

122124
// NOTE: Do not use "thread_local" here. It requires a function call every time

0 commit comments

Comments
 (0)