diff --git a/Miscellaneous Algorithms/twolevel/program.c b/Miscellaneous Algorithms/twolevel/program.c deleted file mode 100644 index e9b406b1..00000000 --- a/Miscellaneous Algorithms/twolevel/program.c +++ /dev/null @@ -1,66 +0,0 @@ -#include -#include -#include - -#define NUM_PROCESSES 5 - -// Structure for process details -struct Process { - int pid; // Process ID - int burstTime; // Burst time of the process - int group; // Group ID (for proportional scheduling) -}; - -// Function to simulate proportional scheduling -void proportionalScheduling(struct Process processes[], int numProcesses) { - int timeQuantum = 2; // Time quantum for each round - int timeElapsed = 0; - - // Keep track of remaining burst times - int remainingBurst[numProcesses]; - for (int i = 0; i < numProcesses; i++) { - remainingBurst[i] = processes[i].burstTime; - } - - printf("Starting Proportional Scheduling...\n"); - - // Continue until all processes are done - while (1) { - int allDone = 1; - - for (int i = 0; i < numProcesses; i++) { - if (remainingBurst[i] > 0) { - allDone = 0; - - // Execute for time quantum or remaining burst time - int execTime = (remainingBurst[i] > timeQuantum) ? timeQuantum : remainingBurst[i]; - remainingBurst[i] -= execTime; - timeElapsed += execTime; - - printf("Process %d (Group %d) ran for %d units\n", processes[i].pid, processes[i].group, execTime); - - // If process finished - if (remainingBurst[i] == 0) { - printf("Process %d completed at time %d\n", processes[i].pid, timeElapsed); - } - } - } - - // Check if all processes are done - if (allDone) break; - } -} - -int main() { - struct Process processes[NUM_PROCESSES] = { - {1, 8, 1}, // Process ID, Burst Time, Group - {2, 4, 2}, - {3, 9, 1}, - {4, 5, 2}, - {5, 7, 1} - }; - - proportionalScheduling(processes, NUM_PROCESSES); - - return 0; -} diff --git a/Miscellaneous Algorithms/twolevel/readme.md b/Miscellaneous Algorithms/twolevel/readme.md deleted file mode 100644 index 641e97fe..00000000 --- a/Miscellaneous Algorithms/twolevel/readme.md +++ /dev/null @@ -1,51 +0,0 @@ -**Two-Level Scheduling** is a CPU scheduling technique used primarily in systems with multiple processors or distributed environments. It separates scheduling into two distinct levels: a high-level (or global) scheduler and a low-level (or local) scheduler. The high-level scheduler assigns processes to specific CPUs, while the low-level scheduler manages the execution of those processes on each individual CPU. This approach allows for more efficient CPU utilization and better performance, especially in multi-core or distributed systems. - -### How Two-Level Scheduling Works - -1. **High-Level Scheduling**: - - In this first stage, the high-level scheduler assigns processes to different CPUs or processors based on factors like CPU load, process priority, and resource requirements. This scheduling happens less frequently and helps balance the load across multiple CPUs. - -2. **Low-Level Scheduling**: - - Once a process is assigned to a CPU, the low-level scheduler (often using algorithms like round-robin, shortest job next, or priority scheduling) manages the execution of processes on that CPU. This level of scheduling operates more frequently, focusing on the efficient and fair use of the CPU it controls. - -### Pros of Two-Level Scheduling - -1. **Improved Load Balancing**: - - The high-level scheduler helps distribute workload across multiple CPUs, avoiding situations where some CPUs are overloaded while others are underutilized. This improves overall system performance and resource usage. - -2. **Enhanced Scalability**: - - By offloading the process distribution responsibility to the high-level scheduler, the system can handle a large number of processes efficiently, making it ideal for multi-core and distributed systems. - -3. **Better Responsiveness and Fairness**: - - With a dedicated scheduler on each CPU, low-level scheduling ensures quick, responsive task handling within each CPU, while the high-level scheduler maintains fairness across CPUs. - -4. **Efficient Multi-Core Usage**: - - Two-level scheduling maximizes the use of multi-core processors by allowing CPUs to independently manage tasks assigned to them, leading to higher throughput. - -5. **Reduced Context Switching**: - - Processes are assigned to a specific CPU by the high-level scheduler, reducing the need for frequent process migrations between CPUs, which minimizes context switching overhead. - -### Cons of Two-Level Scheduling - -1. **Increased Complexity**: - - Managing two levels of scheduling requires more complex algorithms and data structures, especially when balancing load across CPUs and handling process migrations. - -2. **Higher Overhead**: - - The two-layered approach can introduce overhead, as there are now two schedulers operating at different levels. The system needs to track which processes are assigned to which CPUs and manage load distribution. - -3. **Potential CPU Idle Time**: - - If the high-level scheduler doesn't efficiently assign processes to each CPU, it may lead to scenarios where some CPUs remain idle or underutilized, which can reduce efficiency. - -4. **Challenges in Process Migration**: - - Migrating processes between CPUs, if required, can be complex and may cause performance penalties. Process migration often requires additional mechanisms to transfer process states between CPUs without affecting performance. - -5. **Suboptimal for Single-Core Systems**: - - Two-level scheduling adds unnecessary complexity in single-core or less complex environments, where simpler scheduling techniques (like round-robin or priority-based scheduling) would suffice. - -### Use Cases for Two-Level Scheduling - -- **Multi-Core Systems**: In systems with multiple cores or processors, two-level scheduling maximizes core usage and balances the load effectively. -- **Distributed Systems**: In distributed computing environments, where multiple machines or nodes are available, two-level scheduling helps in resource allocation across nodes. -- **Real-Time and High-Performance Applications**: For systems needing high responsiveness and parallelism, such as web servers, scientific computing, or cloud-based applications, two-level scheduling improves resource allocation and responsiveness. - -Overall, two-level scheduling is a powerful approach for handling large-scale and multi-core workloads efficiently. However, it introduces additional complexity and overhead, making it most suitable for high-performance, multi-core, or distributed systems.