1. A method comprising: providing a thread pool including a plurality of thread groups, each thread group including one or more threads; providing a CPU pool including a plurality of CPU groups, each CPU group including one or more CPU cores; receiving a plurality of tasks including I/O tasks and compute tasks; mapping each of the plurality of tasks to at least one thread group in the thread pool; and mapping each of the plurality of thread groups in the thread pool to at least one CPU group in the CPU pool, wherein the mappings between the plurality of tasks and the plurality of thread groups and between the plurality of thread groups and the plurality of CPU groups dynamically change based on performance variables.