When I run PC-DOS on my 4 core AMD Phenom chip, does it take advantage of the extra parallel CPU's? If not, is there a way to coax DOS to use all available CPU's or does this require specific developer programming at the assembly or C compilation time?
-
2Apparently there were Multi-user DOS (not derived from MS-DOS available). https://en.wikipedia.org/wiki/Multiuser_DOS#Multiuser_DOS – Thorbjørn Ravn Andersen Feb 05 '19 at 23:29
-
1You could certainly run DOS multiples times in parallel in VMs, assigning a dedicated CPU to each of them – Thomas Weller Feb 05 '19 at 23:31
-
See also: https://superuser.com/questions/726348/if-dos-is-single-tasking-how-was-multitasking-possible-in-old-version-of-window/726367 – snips-n-snails Feb 06 '19 at 00:46
-
Multi-CPU systems were rare at the time, especially for consumers. The market and the tasks were simply not there yet. – Thorbjørn Ravn Andersen Dec 11 '21 at 16:38
5 Answers
No, DOS won't use any additional CPU (*1) ever.
(Though it might run faster due them new CPUs being faster)
Quite the same way as DOS doesn't take advantage of the extended memory or additional instructions.
DOS is a
- Single CPU
- Single User
- Single Task
- Single Program
- Real Mode
- 8086
operating system.
Even through it got a few extensions over time to tap a bit into newer developments, like
- A20 Handler for HMA usage
- Utilities for extended memory usage like HIMEM.SYS or EMM386
- Usage of certain 286 instructions
it never left its original setup. That's what Unix, OS/2 and Windows NT were meant for.
Similar goes for third party extensions like background utilities (SideKick) or process swappers/switchers (DoubleDos et.al.), or the eventually furthest reaching combination of all, Windows (up to 98). They all added layers to manage DOS for some increased functionality, but didn't (and couldn't) change its basic workings.
Of course, application programs can use additional features of a machine, no matter if it's new CPU instructions, a new graphics card, more memory, or in this case an additional CPU. Much like DOS-extenders allowed protected mode programs to run as DOS applications, most notably maybe DOS/4GW, which got huge popularity due being delivered with Watcom compilers.
Then again, I do not know of any extender allowing the use of concurrent CPUs.
Edit: Stephen Kitt found a lovely new (2015) project, called DOS Multicore Mode Interface, preparing DOS for multi CPU applications. It allows utilization and synchronisation across CPUs and serializes DOS calls between them. (*2)
It's worth noting that none of these additions - including the application specific DOS-extenders - were changing the basic paradigm of DOS as a single-user, single-task operating system.
*1 - What to call it? CPU, core, hyperthread, socket? Well, in ye good olde times of simple microprocessors we couldn't care less. Nowadays it gets blurry. With multiple processing units of various quality it gets hard to qualify. For most purposes the professional world continues to call the device (IC) a CPU, but avoids the term when it comes to system building and talks now about sockets, leaving open how many processing units the IC plugged in will have - or if at all. Often the term core is used instead, but thanks to Intel using this as well as a brand name, it got blurred again. So for all RC.SE purposes I stay with the term CPU, as vague as it is, and qualify if needed.
*2 - Beside potential conflict with BASICA/GWBASIC, it of course works only with applications aware of the extension - and is less than perfect. Still, the very basic approach can already realize most of the potential, especially when taking into account that modern CPUs (the very ones offering more cores) are much faster than mid-1980s predecessors, a little slowdown for DOS access matters even less.
-
Comments are not for extended discussion; this conversation has been moved to chat. – Chenmunka Feb 11 '19 at 10:55
-
3
-
1
-
DIgital Research managed to make Concurrent-CP/M-86 (which I've tried) MS-DOS compatible (which I haven't). Unfortunately they didn't sell well - probably because everyone was waiting on OS/2 right around the corner. – Thorbjørn Ravn Andersen Dec 11 '21 at 16:40
If by IBM DOS you mean IBM PC DOS, which was a rebrand/derivate of MS-DOS, then the answer is no - DOS will only ever support a single core. HyperThreading and multiple cores is simply not supported by DOS.
Making DOS use multiple cores would be a major operation. Firstly DOS would have to support multitasking. It could not be task switching or cooperative multitasking, it would have to be full pre-emptive multitasking. Then it would need to be developed to support SMP (symmetric multiprocessing). Both of these tasks would be major undertakings - their peers in the 90s took years to get reliable and efficient multiprocessing support.
It is possible that a single application could take advantage of multiple cores if it used DOS as a bootstrap and then kicked DOS out, and essentially became its own operating system.
If you're looking for a 90s-era operating system that supports multiple cores, then you would be looking at Linux (2.0 or later), Windows NT 4 or OS/2 Warp.
- 5,531
- 1
- 26
- 59
-
2AFAIK there were only two versions of OS/2 with support for multiple CPUs, OS/2 2.11 SMP and OS/2 Warp 4 AS SMP, and both are very rare. – Stephen Kitt Feb 05 '19 at 13:24
-
2"It could not be task switching or cooperative multitasking, it would have to be full pre-emptive multitasking" <- why? shouldn't it be enough to give each "core" something to do and wait until this something says "hey, I finished"? – Felix Palmen Feb 05 '19 at 14:31
-
@FelixPalmen Because it needs to coordinate across CPUs to do so. This requires a complete set of separate states at least for each CPU - a measure DOS does not support. Adding multi CPU support to a DOS switcher would only supply a partial solution - and not make DOS run on multiple CPU. If at all, it can offer DOS services handled from a single CPU to be used by all others. It'll keep the bottleneck and result in maybe even slower operation than on a single core. – Raffzahn Feb 05 '19 at 16:07
-
@Raffzahn: I would think that it should be possible for a system with multiple hard drives to run several instances of DOS simultaneously, one per core, if all drives that were shared between instances were treated as "read-only", and the instances had no interaction with each other. – supercat Feb 05 '19 at 16:33
-
@supercat As usual, there are many things possible. Including a simple supervisor layer below dos, as you suggest. One that as well catches all other I/O, from keyboard to serial or screen ... and all with some restrictions. But that's not DOS, but some layer oround. DOS itself, as existing and asked for can not do so. – Raffzahn Feb 05 '19 at 16:36
-
Yeah, I mean you can also imagine a cooperative processing queue per core, each spinning when empty via any memory operation that's known to be atomic on an x86. That doesn't technically require much in terms of a scheduler or primitives. But, as per Raffzahn's concern, it also wouldn't be DOS. I think Richard Downer is correct to say pre-emptive multitasking would be necessary in order to use multiple cores to do anything that improves your experience with MS-DOS software. – Tommy Feb 05 '19 at 16:40
-
@Raffzahn: DOS allows loading device drivers for alternative keyboards and such, or taking console input from a COM port. Thinking about it, I guess interrupts might be a problem since one would need an underlying OS to know which interrupts were owned by which sessions, but it might be possible to use drivers that avoided the need for interrupts. – supercat Feb 05 '19 at 16:44
-
@Raffzahn "it needs to coordinate across CPUs to do so. This requires a complete set of separate states at least for each CPU - a measure DOS does not support." -- DOS would need quite some things it doesn't have, I just don't see how preemptive multitasking should be a hard requirement. Why wouldn't cooperative (pass control on I/O and explicit yield) do? – Felix Palmen Feb 05 '19 at 16:59
-
@FelixPalmen I'm unclear how that would allow use of multiple processors, rather than merely multitasking DOS applications on a single processor, in the style of Multitasking MS-DOS 4.0, Concurrent CP/M/Multiuser DOS, or, I assume, the text-mode OS/2s? – Tommy Feb 05 '19 at 17:04
-
@FelixPalmen As this would not only not speed up any DOS application - as there is no parallel execution - but also leave the bottleneck of all I/O going thru one core. Beside, that it would be no feature of DOS, but another middleware on top. – Raffzahn Feb 05 '19 at 17:04
-
2Please feel free to edit my post - I assumed pre-emptive multitasking as a given, but that assumption may not stand up to scrutiny, or at least may be disputed :-) – Richard Downer Feb 05 '19 at 17:08
-
1@Tommy how does cooperative multitasking prevent you from using multiple cores? If a core is idle, do something on it, if not, wait until there's a yield or I/O on one... that's still not preemptive – Felix Palmen Feb 05 '19 at 17:08
-
1@Raffzahn the bottleneck with I/O typically isn't the processing on the CPU but the waiting for the actual device. You'd definitely need a wait-queue for tasks, but not necessarily preemption. – Felix Palmen Feb 05 '19 at 17:11
-
@RichardDowner I think it is well put. It can be disputed, but then everything can in computing, as a simple ans sraight solution can always be replaced by a bloated work around. – Raffzahn Feb 05 '19 at 17:13
-
@RichardDowner I'm just asking for a definitive reason preemption is a must for SMP. Maybe there is one, so I won't just edit ;) – Felix Palmen Feb 05 '19 at 17:13
-
@Raffzahn comparing a preemptive and a cooperative scheduler, the preemptive one is the "bloat". Not really a thing nowadays, it has enough advantages. But it's a lot more complex. – Felix Palmen Feb 05 '19 at 17:16
-
@FelixPalmen Yes, you can - and you can even add even much more layers to solve the issue - or go with a simple preemptive system that can be used on a single or multiple CPU setup. After all, with the endless posibilities of computers, there is an andless number of solutions to a single problem. So the question is less of "can it be done", but rather "does it make sense" - isn't it? – Raffzahn Feb 05 '19 at 17:16
-
1@RichardDowner no, I agree with you. The question is about DOS. It is about running existing DOS software. Existing DOS software very often assumes exclusive ownership of hardware. To run multiple applications at once without each experiencing a whole bunch of surprises, you need to be able to intercede upon hardware accesses. That sort of intercession is called pre-empting. Saying "oh, but you could have offered this service, and then brand new software could have been written to use it" is completely orthogonal to the question posed. – Tommy Feb 05 '19 at 17:19
-
2@FelixPalmen nobody is arguing that "preemption is a must for SMP". They're arguing that preemption is a must for finding a way to do anything useful with multiple cores within the confines of running MS-DOS software. – Tommy Feb 05 '19 at 17:21
-
@FelixPalmen [You may want to wait for an answer directed at you - otherwise it'seven bloating the comment section as well] A preemptive scheduler can be written in very few assembly instruction All it needs it to setup an interrupt source and react to it. After that, the job is done by saving the CPU state and switching for a new one (which a cooperative needs as well). This and everything beyond are already additional services, which either type may support or not, independent of the multitasking scheme. – Raffzahn Feb 05 '19 at 17:22
-
-
Well you could use non-SMP multitasking. DOS runs on the primary core, CPU intensive jobs get fed to the other CPUs (but they must be careful to never execute an
intinstruction or fault for any other reason). – Joshua Feb 05 '19 at 17:25 -
1@Tommy "you need to be able to intercede upon hardware accesses. That sort of intercession is called pre-empting." that differs a lot from the definition of preemption I know: It means "at any time", typically after the end of a time slice. Requesting some I/O from the OS is a distinct and documented time and matches the cooperative category. "It is about running existing DOS software." <- the answer to the question is a clear "no". The rest is thinking about what DOS would need for taking advantage of multiple CPUs. It's illusionary anything could be achieved with unmodified [...] – Felix Palmen Feb 05 '19 at 17:56
-
@Tommy [...] classic DOS applications. Running multiple of these at once isn't the same as a speed improvement. To benefit from multiple CPUs, an application has to know a notion of threads and needs to use some OS APIs for these. – Felix Palmen Feb 05 '19 at 18:02
-
@FelixPalmen to me, pre-emption is merely "stepping in". But in any case I think it's easy to render the distinction moot: amongst the things that DOS software has unfettered access to is the timer. Therefore, if running concurrent DOS programs, multiple may set the timer to different frequencies. Therefore to provide the regular DOS environment, you need itself to capture timer interrupts and decide to whom to forward. So to provide the DOS environment, you need to have something installed that receives timer interrupts and, upon doing so, decides which tasks should then run. – Tommy Feb 05 '19 at 18:10
-
@Tommy yes, but that's the implicit assumption to run unmodified classic DOS applications, which is IMHO quite pointless, they won't run any faster anyways ;) As I said, the answer to OP's question is "no", and anything else is a thought experiment... – Felix Palmen Feb 05 '19 at 18:12
-
Yeah, we're obviously envisioning different use cases. I guess I'm contrasting with the single-core cooperative multitasking DOSes in looking for 'faster'. I can also see some leeway in either direction for how you'd most beneficially use additional cores for things like maintaining a disk cache, or, say, running a TCP/IP stack into which you tunnel IPX/SPX traffic. The former feels like you could do a reasonable job without pre-emptive code, the latter I suspect not. – Tommy Feb 05 '19 at 18:22
-
@Joshua "CPU intensive jobs [...] must be careful to never execute an int instruction" Considering that software interrupts is the main programming interface on MS-DOS/PC-DOS, that means they can't interact with the operating system. That would be quite a limitation if it's the case as written. – user Feb 05 '19 at 20:31
-
@aCVn: You're catching on. They would have to use lock-free atomics to transfer IO requests to the primary CPU. It might be worth it for enough CPU power but ... – Joshua Feb 05 '19 at 20:59
DOS itself won't do anything to boot up the "extra" cores in a multicore system, running only on the boot CPU.
A program that does that is normally called an operating system. You could certainly have a program that takes over from DOS. Maybe even one that saves the previous DOS state and could exit back to DOS. But nobody's written such a thing. You can probably find bootloaders that will load Linux from DOS, though. It would involve taking over the interrupt table and so on.
https://stackoverflow.com/questions/980999/what-does-multicore-assembly-language-look-like includes an answer with some details on what you'd need to do on x86 to bring up other cores to send inter-processor interrupts (IPIs) that bring up other cores.
CPUs with fewer cores tend to have higher guaranteed clock speeds, because each core has a higher power budget. But CPUs that support "turbo" typically have a high single-core turbo clock they can use when other cores are idle.
Modern Intel CPUs with more cores also tend to have more L3 cache; a single core can benefit from all the L3 cache on the whole die. (Not on other CPUs in a multi-socket system, though).
If you're using a DOS extender that allows a DOS program to access more than 1MiB of RAM (e.g. running in 32-bit protected mode), then it might actually benefit from having more than the 3MiB of L3 cache that a low-end dual-core system has.
But otherwise DOS can't use more memory than the smallest L3 caches on modern mainstream x86 CPUs. (Or on Skylake-X, the per-core L2 caches are 1MiB, up from 256kiB, so other than unacheable I/O / device / VGA memory, everything would be a cache hit with 13 cycle latency, much faster than ~45 cycle latency L3 in a dual or quad core!)
But there's a downside to having more cores on Intel CPUs: L3 cache latency. They put a slice of L3 along with each core, and cores + L3 are connected by a ring bus. So more cores means more hops on the ring bus on average to get to the right slice. (This is reportedly even worse on Skylake-X, where a mesh connects cores. It's odd because a mesh should mean fewer hops.)
This extra latency also affects DRAM access, so single-core memory bandwidth is better on dual / quad core desktop CPUs than on big many-core Xeons. Why is Skylake so much better than Broadwell-E for single-threaded memory throughput?. Even though the Xeon has quad-channel or 6-channel memory controllers, a single core can't saturate them and actually has worse bandwidth than a single core of the same clock speed on a quad-core part. Bandwidth is limited by max_concurrency / latency.
(Of course this doesn't apply to L2 cache hits, and 256kiB L2 is a good fraction of the total memory that DOS programs can use without a DOS extender. And 2, 4, or 8 MiB of L3 cache is pretty huge by DOS standards.)
AMD Ryzen is different: it uses "core clusters" which each group of 4 cores share an L3 cache. More total cores won't give you more L3 that a single core can benefit from. But within a cluster, L3 latency is fixed and pretty good.
- 3,207
- 17
- 26
The answers above are correct about the core usage, but it would still be faster than old machines because the clock (MHz/GHz) of the CPU is faster. This is actually problematic on many of the old games because things happen faster than you can react.
If you wanted to test/play without committing to a wipe/load scenario, you could always try FreeDOS on an emulator or on an old hard drive.
- 121
- 2
-
5Actually, the canonical example of speed causing problems wasn't, IMHO, games, but rather Turbo Pascal. There was a bug in certain versions of Turbo Pascal where executables had a timing loop at the beginning and on machines of a certain speed (I think I first saw this with Pentium, but I'm not 100% sure), they would get a runtime error due to, I think, an overflow of an integer variable. Fortunately, someone came up with a patch (I'm sure I still have it here somewhere) that bypassed that code - I would run that as part of the compile process. – manassehkatz-Moving 2 Codidact Feb 05 '19 at 15:26
-
1@manassehkatz The first time I experienced "too fast" was Tetris that originally I had for a 286. When I installed it on a 386, I had to turn off the turbo button for it to be remotely playable. By my 486, it was unplayable :P – UnhandledExcepSean Feb 05 '19 at 15:29
-
Games should, inherently, understand the speed issue and deal with it - even though many did not. Ordinary applications shouldn't have to. One of the complications is that IBM (or maybe it was Microsoft, not sure whose idea it was) came up with the 18.2 ticks per second - when plenty of other systems already used 60 ticks per second. That is fine for typical application timing purposes but way too slow for interactive games - so every game came with its own method of timing and many of those methods really failed past a certain CPU speed (or simply didn't adapt at all and assumed 4.77 Mhz). – manassehkatz-Moving 2 Codidact Feb 05 '19 at 15:45
-
2For the record, I had to use the Turbo Pascal patch program in order to run Turbo Pascal software on a Pentium 200 (non-MMX) if memory serves. But only in real DOS, not when running inside Windows 95. So the speed of execution that causes its startup code to attempt a divide by zero must be somewhere close below that of an unencumbered P200. – Tommy Feb 05 '19 at 16:36
-
1@manassehkatz, 18.2 Hz was 1/65536th of 1/12th of 4 times the 4.77 MHz NTSC color subcarrier frequency. Fortunately, the timer could be adjusted to produce other frequencies. – Mark Feb 05 '19 at 20:55
-
3@manassehkatz There was also the problem that the computers were so slow that adding any timing methods would make the game run slow. And many systems shipped with a "Turbo" button that restricted the speed back to a fairly standard rate, so the slowdown could be handled in hardware. – trlkly Feb 06 '19 at 06:07
When PC starts, it launches only one CPU core (so called bootstrap CPU). OS is executed on this CPU. Then, OS starts other cores by sending IPI (inter processor interrupt). To do this, OS first switches PIC (interrupt controller) to APIC (advanced) mode and uses its registers.
DOS is not aware of other CPUs and APIC, and does not know how to send IPI.
So, DOS can't even start other cores. They simply turned off and do not work.
If you want to use them, you would have to deal with APIC by yourself. It is not easy task, though. See https://wiki.osdev.org/Symmetric_Multiprocessing
- 211
- 2
- 2
-
i bet that the "solution" would be to write some kind of "driver" inside of DOS that would enable access to the APIC. (and if mode switching required, fake everything and make it appear as if DOS was still in real mode) sort of like how the "dos extenders" (see above answer) allowed DOS programs to access more than 1 MB of RAM. Theoretically if the machine had a GPU, and a OpenCL "driver" for DOS, you should be able to use a GPU as a coprocessor. After all, the original 8086, and 286, and maybe 386 allowed you to buy a "Math Coprocessor" which had a floating point unit inside of it. – don bright Feb 07 '19 at 00:25