# Practical Enhancement of User Experience in NVMe SSDs
## 4 Performance Evaluation  
The experimental environment is presented in Table 1. To emulate the I/O intensive applications, we used a _flo_ benchmark tool that is widely used for generating I/O workloads with various configurations [30; 31]. For enough I/O workloads, 50 fio tasks continuously generating random read requests were executed: one of them was set as a user-centric task, and the others were set as non-user-centric tasks. As mentioned earlier, the type of tasks is determined by the priority of each task. To verify the effectiveness of the ideas employed in the proposed scheme, performance evaluations were performed under the various combinations of ideas as described in Table 2. Note that we repeated all experiments 10 times to make the results reliable. Figure 5 depicts the performance of the proposed scheme in terms of execution time, input/output operations per second (IOPS), and I/O bandwidth. This plot only shows the average value of the repeated experiments because the deviation is negligibly small. It can be observed that merely increasing the priority of user-centric tasks resulted in a significant performance boost (_high-priority_). In this case, the execution time, IOPS, and I/O bandwidth of user-centric tasks improved by 10.50%, 11.79%, and 11.49%, respectively, compared to the original kernel. In addition, when additional SQs were assigned to handle user-centric tasks (_separated_) and I/O requests from user-centric tasks were sent to the shortest submission queue (_shortest_), all metrics improved by up to 14.62% and 16.75%,  
Figure 4: Flow chart of the proposed multi-queue block layer. respectively. When all ideas were employed together (_proposed_), all metrics of user-centric tasks improved by up to 19.54%. Likewise, the use of the proposed scheme also seemed to improve the performance of non-user-centric tasks by up to 2.89%. It seems to be because, in our experiment environment, after a Rio task executed as a user-centric task outputs the results and exits, Rio tasks executed as non-user-centric tasks used the remaining resources. This behavior could be also observed in the average I/O latency, which was measured in the block I/O layer. The average latency of I/O requests from user-centric tasks is improved from 23.57 us to 20.53 us, while that of I/O requests from non-user-centric tasks is slightly improved from 23.57 us to 22.20 us. Figure 6 depicts the launch times of five widely used Linux programs (Table 3), which is a crucial metric for users. As they are rather large programs using window, many files such as executables, configurations, and libraries should be read for the start-up. It inevitably entails a long latency and it can make users wait longer if the storage is overburdened. We measured the launch times while several _fio_ workloads ran in the background. We can measure the start time of application by monitoring when _exec()_ in shell is called, but it is not easy to clearly define and measure the completion of a launch. In our experiments, as all applications are using window, we measured the completion time of a launch by monitoring when window is created with _wmctrl_. Compared to using the original scheme, the use of the proposed scheme improved the launch times of the five programs on average by 28.42%, 48.71%, 63.54%, 59.83%, and 65.13%, respectively. As shown in the figure, the deviation of launch times is quite large depending on the system situation, but the proposed scheme consistently shows a significant performance improvement in all experiments. As the launch time can significantly affect user experience, these improvements are more substantial than the results of previous experiments, which were on accumulated performance improvement.