summaryrefslogtreecommitdiffstats
path: root/src/stateless/cp/trex_vm_splitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/stateless/cp/trex_vm_splitter.cpp')
-rw-r--r--src/stateless/cp/trex_vm_splitter.cpp127
1 files changed, 35 insertions, 92 deletions
diff --git a/src/stateless/cp/trex_vm_splitter.cpp b/src/stateless/cp/trex_vm_splitter.cpp
index 5069c535..1ff43829 100644
--- a/src/stateless/cp/trex_vm_splitter.cpp
+++ b/src/stateless/cp/trex_vm_splitter.cpp
@@ -89,27 +89,28 @@ TrexVmSplitter::split(TrexStream *stream, std::vector<TrexStream *> core_streams
bool
TrexVmSplitter::split_internal() {
- const StreamVmInstructionVar *split_instr = m_stream->m_vm.get_split_instruction();
+ duplicate_vm();
+
+ /* search for splitable instructions */
+ for (StreamVmInstruction *instr : m_stream->m_vm.get_instruction_list()) {
+ if (!instr->is_var_instruction()) {
+ continue;
+ }
+
+ split_flow_var( (const StreamVmInstructionVar *)instr );
- /* if no split instruction was specified - fall back*/
- if (split_instr == NULL) {
- return false;
}
- if (split_instr->get_instruction_type() == StreamVmInstruction::itFLOW_MAN) {
- return split_by_flow_var( (const StreamVmInstructionFlowMan *)split_instr );
- } else if (split_instr->get_instruction_type() == StreamVmInstruction::itFLOW_CLIENT) {
- return split_by_flow_client_var( (const StreamVmInstructionFlowClient *)split_instr );
+ /* done - now compile for all cores */
+ compile_vm();
- } else {
- throw TrexException("VM splitter : cannot split by instruction which is not flow var or flow client var");
- }
+ return true;
}
/**
- * split VM by flow var
+ * split a flow var instruction
*
* @author imarom (20-Dec-15)
*
@@ -117,98 +118,29 @@ TrexVmSplitter::split_internal() {
*
* @return bool
*/
-bool
-TrexVmSplitter::split_by_flow_var(const StreamVmInstructionFlowMan *instr) {
- /* no point in splitting random */
- if (instr->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM) {
- return false;
- }
-
- /* if the range is too small - it is unsplitable */
- if (instr->get_splitable_range() < m_dp_core_count) {
- return false;
- }
-
- /* split only step of 1 */
- if (!instr->is_valid_for_split() ){
- return false;
+void
+TrexVmSplitter::split_flow_var(const StreamVmInstructionVar *src) {
+ /* a var might not need split (random) */
+ if (!src->need_split()) {
+ return;
}
- /* we need to split - duplicate VM now */
- duplicate_vm();
-
- /* calculate range splitting */
- uint64_t range = instr->get_splitable_range();
-
- uint64_t range_part = range / m_dp_core_count;
- uint64_t leftover = range % m_dp_core_count;
-
- /* first core handles a bit more */
- uint64_t start = instr->m_min_value;
- uint64_t end = start + range_part + leftover - 1;
-
-
/* do work */
+ int core_id = 0;
for (TrexStream *core_stream : *m_core_streams) {
- /* get the per-core instruction to split */
- StreamVmInstructionFlowMan *per_core_instr = (StreamVmInstructionFlowMan *)core_stream->m_vm.get_split_instruction();
-
- per_core_instr->m_min_value = start;
- per_core_instr->m_max_value = end;
+ StreamVmInstructionVar *dst = core_stream->m_vm.lookup_var_by_name(src->get_var_name());
+ assert(dst);
- /* after split this has no meaning - choose it as we see fit */
- per_core_instr->m_init_value = (per_core_instr->m_op == StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC ? end : start);
+ /* for each core we need to give a phase and multiply the step frequency */
+ dst->update(core_id, m_dp_core_count);
- core_stream->vm_compile();
-
- start = end + 1;
- end = start + range_part - 1;
+ core_id++;
}
- return true;
}
-bool
-TrexVmSplitter::split_by_flow_client_var(const StreamVmInstructionFlowClient *instr) {
-
- /* if the range is too small - it is unsplitable */
- if (instr->get_ip_range() < m_dp_core_count) {
- return false;
- }
-
- /* we need to split - duplicate VM now */
- duplicate_vm();
-
- /* calculate range splitting */
- uint64_t range = instr->get_ip_range();
-
- uint64_t range_part = range / m_dp_core_count;
- uint64_t leftover = range % m_dp_core_count;
-
- /* first core handles a bit more */
- uint64_t start = instr->m_client_min;
- uint64_t end = start + range_part + leftover - 1;
-
-
- /* do work */
- for (TrexStream *core_stream : *m_core_streams) {
-
- /* get the per-core instruction to split */
- StreamVmInstructionFlowClient *per_core_instr = (StreamVmInstructionFlowClient *)core_stream->m_vm.get_split_instruction();
-
- per_core_instr->m_client_min = start;
- per_core_instr->m_client_max = end;
-
- core_stream->vm_compile();
-
- start = end + 1;
- end = start + range_part - 1;
- }
-
- return true;
-}
/**
* duplicate the VM instructions
@@ -222,3 +154,14 @@ TrexVmSplitter::duplicate_vm() {
}
}
+/**
+ * now compile the updated VM
+ */
+void
+TrexVmSplitter::compile_vm() {
+ /* for each core - duplicate the instructions */
+ for (TrexStream *core_stream : *m_core_streams) {
+ core_stream->vm_compile();
+ }
+}
+