Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dosbox-staging/dosbox-staging.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkcgen <1557255+kcgen@users.noreply.github.com>2020-08-10 19:22:26 +0300
committerkcgen <kcgen@users.noreply.github.com>2022-11-04 06:12:50 +0300
commit4e63f1723ab570c7adb251c965aa4699f53cb75b (patch)
treedea54b2bb630f443b3ef895b937419113dfcbf45
parente9489b0763ce743f240c53ad06d2b54349b7d52a (diff)
Add configurable queue depth and min cycle percent to scheduler
-rw-r--r--src/cpu/cpu.cpp2
-rw-r--r--src/dosbox.cpp85
2 files changed, 74 insertions, 13 deletions
diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp
index 334ccb868..9f86ff8e0 100644
--- a/src/cpu/cpu.cpp
+++ b/src/cpu/cpu.cpp
@@ -2128,7 +2128,7 @@ static void CPU_CycleIncrease(bool pressed) {
CPU_CycleLeft=0;CPU_Cycles=0;
if (CPU_CycleMax==old_cycles) CPU_CycleMax++;
- LOG_MSG("CPU speed: fixed %d cycles.",CPU_CycleMax);
+ LOG_MSG("CPU speed: fixed %d cycles.", CPU_CycleMax);
GFX_SetTitle(CPU_CycleMax,-1,false);
}
}
diff --git a/src/dosbox.cpp b/src/dosbox.cpp
index de0ee3cb1..88ba104c8 100644
--- a/src/dosbox.cpp
+++ b/src/dosbox.cpp
@@ -32,6 +32,7 @@
#include <string.h>
#include <thread>
#include <unistd.h>
+#include <vector>
#include "debug.h"
#include "cpu.h"
@@ -63,6 +64,14 @@
#include "tracy.h"
#include "video.h"
+constexpr double FRAME_RATE = 60.0;
+constexpr uint8_t MAX_FRAME_QUEUE = 9;
+constexpr int MIN_CYCLES_PERCENT = 33; // valid range: 1% to 100%
+
+#if C_NE2000
+//#include "ne2000.h"
+void NE2K_Init(Section* sec);
+#endif
// Shorthand for our clock and time units
using clockT = std::chrono::steady_clock;
@@ -159,9 +168,10 @@ bool mono_cga=false;
void increaseticks_fixed();
-static constexpr auto frame_pace_us = usT(1000 * 1000 / 60);
-static constexpr uint32_t frame_pace_ms = frame_pace_us.count() / 1000;
-static int32_t target_cycles;
+static constexpr auto frame_pace_us = usT(static_cast<int>(1000000.0 / FRAME_RATE));
+static constexpr auto frame_pace_ms = static_cast<uint32_t>(frame_pace_us.count()) / 1000;
+static constexpr auto max_latency_ms = static_cast<uint32_t>(frame_pace_us.count()) * MAX_FRAME_QUEUE /
+ 1000;
static int frame_balance = 0;
static int pic_balance = 0;
@@ -170,6 +180,59 @@ static std::thread frame_pacer;
static std::mutex pic_balance_mutex;
static std::mutex frame_balance_mutex;
+static std::vector<int32_t> cycle_range;
+const std::vector<int32_t> generate_cycle_range(const int32_t max_cycles,
+ int min_percent)
+{
+ // Bound valid values between 1% and 100%
+ min_percent = std::clamp(min_percent, 1, 100);
+ const double min_cycles = max_cycles * min_percent / 100.0;
+
+ std::vector<int32_t> range;
+ for (double c = min_cycles; c < max_cycles; c *= 1.07) {
+ const auto cycles = static_cast<int32_t>(c);
+ range.push_back(cycles);
+ LOG_MSG("SCHED: range %d", cycles);
+ }
+ range.push_back(max_cycles);
+ return range;
+}
+
+static std::vector<int32_t>::iterator cycle_selector;
+bool cycles_below_max()
+{
+ return cycle_selector < cycle_range.end();
+}
+
+void increase_cycles(const uint32_t current_latency_ms)
+{
+ static uint8_t decimator = 0;
+ decimator = (decimator + 1) % 20;
+ if (cycles_below_max() && decimator == 0) {
+ ++cycle_selector;
+ CPU_CycleMax = cycle_selector == cycle_range.end()
+ ? cycle_range.back()
+ : *cycle_selector;
+ LOG_MSG("SCHED: %u ms queue, increased cycles to %u",
+ current_latency_ms, CPU_CycleMax);
+ }
+}
+
+bool cycles_above_min()
+{
+ return cycle_selector > cycle_range.begin();
+}
+
+void decrease_cycles(const uint32_t current_latency_ms)
+{
+ if (cycles_above_min()) {
+ --cycle_selector;
+ CPU_CycleMax = *cycle_selector;
+ LOG_MSG("SCHED: %u ms queue, decreasing cycles to %u",
+ current_latency_ms, CPU_CycleMax);
+ }
+}
+
static void pace_pic()
{
while (true) {
@@ -230,14 +293,11 @@ void increaseticks_fixed()
ticksRemain = ticksNew - ticksLast;
ticksLast = ticksNew;
- if (ticksRemain > frame_pace_ms) {
- CPU_CycleMax -= CPU_CycleMax / 10;
- ticksRemain = frame_pace_ms;
- LOG_MSG("Dropped cycles to %u", CPU_CycleMax);
- }
- else if (ticksRemain > 3 && CPU_CycleMax < target_cycles) {
- CPU_CycleMax += CPU_CycleMax / 25;
- LOG_MSG("Bumped cycles to %u", CPU_CycleMax);
+ if (ticksRemain > max_latency_ms && cycles_above_min()) {
+ decrease_cycles(ticksRemain);
+ ticksRemain = max_latency_ms;
+ } else if (ticksRemain && cycles_below_max()) {
+ increase_cycles(ticksRemain);
}
return;
}
@@ -393,11 +453,12 @@ void DOSBOX_RunMachine()
{
static bool started = false;
if (!started) {
+ cycle_range = generate_cycle_range(CPU_CycleMax, MIN_CYCLES_PERCENT);
+ cycle_selector = cycle_range.end();
pic_pacer = std::thread(&pace_pic);
pic_pacer.detach();
frame_pacer = std::thread(&pace_frame);
frame_pacer.detach();
- target_cycles = CPU_CycleMax;
started = true;
}