# A Baseband Wireless Spectrum Hypervisor for Multiplexing Concurrent OFDM Signals
## 8 Experimental Evaluation
Figure 21: Data PRR curves for a setup with 12 vPHYs with their signals multiplexed by the prototype and using: (**a**) MCS0 (QPSK), (**b**) MCS16 (16 QAM), and (**c**) MCS28 (64 QAM). Figure 20: Prototype’s throughput for single and 12 vPHYs over different MCS values. Figure 22 depicts the CPU and memory use of the prototype for several MCS values. These results compare CPU and memory use when the prototype must multiplex the signal of 1 and 12 vPHYs, respectively. The results in the figure were calculated by averaging CPU and memory usage values sampled every 200 ms during the duration of the experiment, which was set to 60 s. Each one of the vPHYs transmit 20 subframes in a row with a 1 ms gap between consecutive transmissions. As can be observed, the CPU use increases as the MCS increases; however, there is no CPU starvation issue. The increase in CPU use is mainly due to the fact that as the MCS value increases (i.e., higher data rates), the turbo encoding (at Tx side), synchronization and turbo decoding (both at Rx side) processing tasks become more complex and consequently demand a lot more of CPU for data processing. For a MCS equal to 28 and 12 vPHYs concurrently transmitting, the CPU use is of approximately 450%, meaning that the processing power of fewer than 5 cores is being employed, leaving the other cores in the idle state for large periods. On the other hand, we see that the memory use is practically constant for all MCS values and goes from around 0.5% to 2.2% for 1 and 12 vPHYs, respectively. Therefore, memory use is practically independent of the MCS value being used. This is an expected result as all memory being used by the prototype is pre-allocated during its initialization. Therefore, based on the results presented in Figure 22, it can be concluded that the prototype does not exhaust CPU or memory resources as the MCS value increases. These are important results, once they show that given the current server configuration, the prototype can be scaled to support even more vPHYs without exhausting CPU or memory resources. Next, in Figure 23, we present the assessment of the CPU consumption of independent processing tasks making up the architecture prototype. For this assessment we employ the _callgrind_ tool, which is part of the _valgrind_ profiler. _Callgrind_ is a profiling tool that keeps the call history among functions in a program's run as a call-graph through the use of runtime instrumentation [62; 17]. The figure presents the functions with the highest CPU processing load (i.e., the most representative CPU consumers) for 3 different MCS values and the cases where 1 and 12 vPHYs are instantiated. The setup used for this experiment is the same as the one used during the experiment for CPU and memory profiling. Figure 22: CPU and memory use of the architecture prototype for 1 and 12 vPHYs. As can be noticed, channelization presents the highest CPU consumption throughout all test cases. Channelization is a quite heavy processing once it keeps always processing a bandwidth equivalent to the maximum number of configured vPHYs, which in this case is equal to 12, no matter the number of actually instantiated vPHYs. For 1 instantiated vPHY, inverse FFT is the second most consuming task; however, its CPU consumption remains constant for all considered MCS values as it does not depend on the MCS used. In the case that 12 vPHYs are instantiated, we see that memory copy, _memcpy_, increases its load from 15.35% for MCS 0 to approximately 20% for MCS 28. Compared to the 1 vPHY case, it is a drastic increase once it has a maximum CPU load of 7.41% for MCS 28. For the 12 vPHYs case, the inverse FFT is the third most consuming task, ranging from 20.04% for a MCS equal to 0 to 12.37% for a MCS equal to 28. We see that in the second column, the one for 12 instantiated vPHYs, the IFFT processing load gradually decreases while _memcpy_ gradually increases its CPU load.