• We have updated our Community Code of Conduct. Please read through the new rules for the forum that are an integral part of Paradox Interactive’s User Agreement.

Emren

Brigadier General
68 Badges
Feb 27, 2001
1.445
904
  • Europa Universalis IV: Rule Britannia
  • Hearts of Iron IV: No Step Back
  • Europa Universalis 4: Emperor
  • Battle for Bosporus
  • Stellaris: Federations
  • Stellaris: Ancient Relics
  • Europa Universalis IV: Golden Century
  • Europa Universalis IV: Dharma
  • Stellaris: Distant Stars
  • Stellaris: Apocalypse
  • Stellaris: Synthetic Dawn
  • 500k Club
  • Europa Universalis IV
  • Hearts of Iron IV: Cadet
  • Stellaris
  • Victoria 2: A House Divided
  • Crusader Kings II
  • Europa Universalis IV: Pre-order
The thing about unit count...

The AI tends to fare better when it has a high unit count - I believe this was stated by one of the devs at one point in the past four years. So if mods reduce the number of units, it is also reasonable to expect poorer AI handling. So all things equal, if unit count goes down, really, the province fidelity needs to be lowered to match, i.e., we should have a map with less, but larger, provinces. This would keep the AI's performance with a lower unit count.
 

FindFloppies

Some Assembly Required
88 Badges
Jul 8, 2015
852
1.468
  • Cities: Skylines Deluxe Edition
  • Europa Universalis IV: Cossacks
  • Stellaris
  • Europa Universalis IV: Cradle of Civilization
  • Crusader Kings II: Reapers Due
  • Europa Universalis IV: Common Sense
  • Crusader Kings II: Horse Lords
  • Hearts of Iron IV: Expansion Pass
  • Crusader Kings II: Conclave
  • Europa Universalis IV: Dharma
  • Stellaris: Galaxy Edition
  • Hearts of Iron IV: Cadet
  • Hearts of Iron IV: Colonel
  • Battle for Bosporus
  • Europa Universalis IV: Rights of Man
  • Stellaris: Digital Anniversary Edition
  • Stellaris: Leviathans Story Pack
  • Cities: Skylines - Natural Disasters
  • Hearts of Iron IV: Together for Victory
  • Crusader Kings II: Monks and Mystics
  • Crusader Kings III
  • Cities: Skylines - Mass Transit
  • Europa Universalis IV: Mandate of Heaven
  • Stellaris: Federations
  • Hearts of Iron IV: Death or Dishonor
  • Cities: Skylines - Green Cities
  • Stellaris: Nemesis
  • Crusader Kings II: Rajas of India
  • Crusader Kings II: Sunset Invasion
  • Stellaris: Distant Stars
  • Victoria 3 Sign Up
  • Europa Universalis IV
  • Cities: Skylines - Parklife Pre-Order
  • Stellaris: Lithoids
  • Cities: Skylines - Campus
  • Stellaris: Apocalypse
  • Europa Universalis 4: Emperor
  • Hearts of Iron IV: No Step Back
  • Crusader Kings II: Way of Life
  • Hearts of Iron IV: Expansion Pass
  • Stellaris: Humanoids Species Pack
  • Crusader Kings II: Holy Fury
  • Stellaris: Ancient Relics
  • Victoria 2
  • Cities: Skylines - Parklife
  • Stellaris: Necroids
  • Cities: Skylines
  • Europa Universalis III: Collection
  • Hearts of Iron IV: By Blood Alone
  • Europa Universalis IV: Golden Century
Correct. Better you can´t say it. A medium high End or High End PC is the Stage of the Art. For about 1.500 Bucks to 1.800 Bucks you can get a very good Computer incl. Graphics Card from the prevouis Generation for the next 10 to 12 Years or longer incl. Win 10.

Not the Games are the Problem, it´s the overolded Laptop / PC with 20 Years Lifetime and Windows XP etc. which is doing the Laggs.
To be clear, this is no 'high-end gaming rig'. I have a 6-core i-7 3.2 GHz, a 5 GB GTX 1070 GPU, 32 GB RAM, and the OS runs on a mid-range SSD. The game runs from my 2 TB HDD.

I actually run VMs for development testing on this thing, but it games pretty well, too.
 

jpd

Entil'Zha Anla'Shok
Moderator
41 Badges
Apr 19, 2001
8.038
1.757
  • Europa Universalis IV
  • Hearts of Iron IV: No Step Back
  • Hearts of Iron IV: By Blood Alone
  • Battle for Bosporus
  • Stellaris: Ancient Relics
  • Hearts of Iron IV: Expansion Pass
  • Stellaris: Distant Stars
  • Stellaris: Apocalypse
  • Stellaris - Path to Destruction bundle
  • Hearts of Iron II: Beta
  • Arsenal of Democracy
  • Hearts of Iron IV: Field Marshal
  • Hearts of Iron IV: Colonel
  • Hearts of Iron IV: Cadet
  • Hearts of Iron IV: Death or Dishonor
  • Hearts of Iron IV: Expansion Pass
  • Hearts of Iron IV: La Resistance
For all those that say: "just use more cores, and everything is solved", here are some things to consider. It's not as simple as it sounds.

For each task you want to run in parallel to other tasks, you need to create a separate thread of execution. And that comes with overhead. And that overhead is quite significant.

Say, for example, you have a very simple task of: object->myCounter = object->myCounter + 1. And you need this to run for ten thousand objects. Creating 10 thousand threads for it most surely isn't the best solution. Yes, creating 10 thousand threads (one for each individual object) creates the best opportunity to spread them around all of your existing cores. However (and using sample numbers here), the basic code that needs to run is perhaps 10 machine instructions long. Creating each thread, and setting them up to run the code on the correct object, would be in the ballpark of 500 machine instructions. Probably even more (I can't peek inside Microsoft's internal code for creating a thread, but this is based on my own multi processing kernel I made 30 years ago to run atop of MSDOS). So, in order to take max advantage of all cores available, you just increased the grand total of 100,000 machine instructions to 5,100,000 machine instructions. And that's even completely ignoring the additional overhead you place on the process scheduler in the kernel.

Granted, this is an extreme example (minimum work to be done in parallel vs. the overhead parallelism creates), but it demonstrates the basic issue of the additional overhead. If this example was the workload, then the best solution is to run it in serial on one single core, as that still takes the least amount of real time.

Staying with this example, what if you used less threads than one thread per object? Now you get into the realm of thread pools. And you must do (in part) your own scheduling. Because you now have to decide which objects are processed by which existing thread in the thread pool. Again (you guessed it), in comes additional overhead.

For each of these cases, there will be a break even point with the number of cores where spreading among more cores will bring down the overall real time to get the job done. But, for the sake of argument, say this break even point happens to be 9 cores. Then anyone with an AMD Threadripper is a happy camper (yay, my time goes down, no more lag), but anyone with a Core2Duo is a sad camper, because, due to the additional overhead, he just got saddled with more lag than the old solution with everything calculated on a single core.

And this is assuming that the calculations can be fully done in parallel, with none of the objects needing input (or calculated results) from other objects. If that's not the case (and it rarely is), then you need mechanisms where objects signal that their calculations are complete. And that other objects need to halt their work until those results become available. This, again, adds extra overhead, eating up additional CPU cycles. Which are not used for the actual calculations, but merely for housekeeping/coordination. Which you can completely do away with when everything is calculated on a single core.

And this isn't even taking hardware constraints into consideration.

A lot of CPU's have a function called HyperThreading. This fakes additional cores. For each real core, a virtual extra core is created. Yes, each real core can run two threads concurrently due to this, but not at the same time. Each time one thread gets stalled while waiting for access to memory (for reading or writing), the other thread is allowed to run for a bit. This makes both threads appear to be a little faster. But not twice as fast. Not even close to that. At best, you gain some 10%.. And if your additional overhead needs 30% extra CPU time, congratulations, you just made everything 20% slower by utilizing the fake cores as if they were extra cores.

And then there is the tricky business of the thermal envelope. Each CPU is designed for a maximum amount of power it can draw, to prevent it from overheating. If you run work on more cores, the CPU gets hotter. And, to prevent it from going outside of the thermal envelope, the CPU scales back the clock speed. Or, in reverse, if you run calculations on one of the cores, the clock speed can increase. This is what Intel calls TurboBoost. Which throws in another moving part in the determination if doing things on a single core in serial is faster than spreading the work out over multiple cores.
 
  • 3
  • 3
  • 1Like
Reactions:

STABBY5

Lt. General
58 Badges
Feb 13, 2016
1.257
1.145
  • Crusader Kings II: Charlemagne
  • Europa Universalis IV: Res Publica
  • Europa Universalis IV: Call to arms event
  • Europa Universalis IV: Wealth of Nations
  • Europa Universalis IV: Conquest of Paradise
  • Europa Universalis IV: Art of War
  • Crusader Kings II
  • Crusader Kings II: Sword of Islam
  • Crusader Kings II: Sunset Invasion
  • Crusader Kings II: Sons of Abraham
  • Crusader Kings II: The Republic
  • Crusader Kings II: Rajas of India
  • Crusader Kings II: The Old Gods
  • Crusader Kings II: Legacy of Rome
  • Crusader Kings II: Monks and Mystics
  • Stellaris: Lithoids
  • Stellaris: Federations
  • Surviving Mars
  • Hearts of Iron IV: Death or Dishonor
  • Stellaris: Synthetic Dawn
  • Age of Wonders III
  • Crusader Kings II: Jade Dragon
  • Hearts of Iron IV: Expansion Pass
  • Stellaris: Humanoids Species Pack
  • Stellaris: Apocalypse
  • Hearts of Iron IV: Expansion Pass
  • Stellaris: Distant Stars
  • Hearts of Iron IV: No Step Back
  • Crusader Kings II: Holy Fury
  • Hearts of Iron IV: La Resistance
  • Prison Architect
  • Stellaris: Ancient Relics
  • Europa Universalis IV: Common Sense
  • Europa Universalis IV
  • Stellaris: Necroids
  • Victoria 2
  • Battle for Bosporus
  • Stellaris: Nemesis
  • War of the Roses
  • Europa Universalis IV: El Dorado
  • Mount & Blade: With Fire and Sword
  • Crusader Kings II: Way of Life
  • Hearts of Iron IV: Together for Victory
  • Crusader Kings II: Horse Lords
  • Crusader Kings II: Conclave
  • Stellaris
  • Hearts of Iron IV: Cadet
  • Hearts of Iron IV: Colonel
  • Crusader Kings II: Reapers Due
  • Stellaris: Digital Anniversary Edition
In terms of laws of physics or similar, it's nothing.
Okay but its distinctly not physics or similar. Computing has advanced enormously since then in a way that most other sciences have not. The first intel penium processor is from 1993 at whole 60 MHz. My current CPU is at 3.5 GHz. I assume the same basic principals apply now as they did then but I'm merely suggesting that multithreaded processing is not a new technology anymore and that after 25 years we may have optimized it better. Though paradox is not exactly using cutting edge technology either.
 
  • 1
Reactions:

SophieX

Major
May 9, 2014
558
505
Computing has advanced enormously since then in a way that most other sciences have not.

No.
It was a question of production-methods. To reach the capability to build thousand of tyristors and diodes into one small chip. That was the "breaktrough".
 
  • 1Like
Reactions:

GSP Jr

Colonel
15 Badges
Apr 27, 2017
1.159
983
  • Hearts of Iron IV: Cadet
  • Hearts of Iron IV: Colonel
  • Hearts of Iron IV: Field Marshal
  • Hearts of Iron IV: Death or Dishonor
  • Hearts of Iron IV: Expansion Pass
  • Hearts of Iron IV: Expansion Pass
  • Hearts of Iron IV: La Resistance
  • Battle for Bosporus
  • Hearts of Iron IV: By Blood Alone
  • Hearts of Iron IV: No Step Back
  • For the Motherland
  • Hearts of Iron III
  • Hearts of Iron III: Their Finest Hour
  • Hearts of Iron III Collection
  • Semper Fi
Maybe, just maybe, your computer needs maintenance and hardware upgrades.
Get rid of bloatware (Looking at you Dell), defrag drives, turn off unneeded crap, you may be surprised.
 
  • 1Like
Reactions:

Simon_9732495

Lt. General
25 Badges
Feb 28, 2020
1.612
4.188
  • Crusader Kings II
  • Crusader Kings III
  • Europa Universalis IV
  • Europa Universalis IV: Rights of Man
  • Europa Universalis IV: Art of War
  • Europa Universalis IV: Common Sense
  • Victoria 2
  • Cities: Skylines
  • Cities: Skylines Industries
  • Cities: Skylines - Parklife
  • Cities: Skylines - Mass Transit
  • Cities: Skylines - Snowfall
  • Cities: Skylines - After Dark
  • Prison Architect
  • Stellaris
  • Hearts of Iron III
  • Hearts of Iron IV: Cadet
  • Hearts of Iron IV: Together for Victory
  • Hearts of Iron IV: Death or Dishonor
  • Hearts of Iron IV: Expansion Pass
  • Hearts of Iron IV: Expansion Pass
  • Hearts of Iron IV: La Resistance
  • Battle for Bosporus
  • Hearts of Iron IV: No Step Back
  • Hearts of Iron IV: By Blood Alone
For all those that say: "just use more cores, and everything is solved", here are some things to consider. It's not as simple as it sounds.

This!

I found some older quotes on this topic:

If an application is multithreaded, like HOI4 is, it will run on any available core. The core usage at any given time is dependent on the code that is currently running.

For example, if a game is at the main menu, no game logic is running. There's no combats to run, there is no production. Events are not being checked for and there's no units to move around. That means that the amount of running threads is reduced compared to when you are playing the game.

The bottom line is, the game is multithreaded and will use any available core that it needs. Like any other application, multithreading doesn't mean that it will always utilize all cores. We're definitely not making the most out of multithreading that we could, but that's because of the way the game works. Sometimes task can be run in parallel - for example processing production for every country in the world - but other times the game logic will need to run in its own thread.

HOI4 runs a lot of calculations due to the game mechanics. There's (usually) room for optimizations though. We try to optimize the game whenever we can - for example by removing unnecessary calculations, or reducing the complexity of the game logic - but there's often not enough time to do as much as we'd like to. The problem is that games today are more computationally complex than older games and computational complexity often does not scale linearly, especially for mechanics heavy games. :)

There are also bottlenecks that are out of our control. For example, the DX9 renderer is not as fast as a more modern renderer. I'm sure future titles will drop support for DX9, but we still support it. That means that we can't run multithreaded rendering. IO tasks (reading from disk) is also something we can't run in parallel as that would actually decrease performance quite a lot due to IO latency.

Source: Reddit Link
 
  • 1
Reactions:

jpd

Entil'Zha Anla'Shok
Moderator
41 Badges
Apr 19, 2001
8.038
1.757
  • Europa Universalis IV
  • Hearts of Iron IV: No Step Back
  • Hearts of Iron IV: By Blood Alone
  • Battle for Bosporus
  • Stellaris: Ancient Relics
  • Hearts of Iron IV: Expansion Pass
  • Stellaris: Distant Stars
  • Stellaris: Apocalypse
  • Stellaris - Path to Destruction bundle
  • Hearts of Iron II: Beta
  • Arsenal of Democracy
  • Hearts of Iron IV: Field Marshal
  • Hearts of Iron IV: Colonel
  • Hearts of Iron IV: Cadet
  • Hearts of Iron IV: Death or Dishonor
  • Hearts of Iron IV: Expansion Pass
  • Hearts of Iron IV: La Resistance
30 years ago is a long time in terms of technology.
This is very true.

30 years ago, you didn't have separation between USER space and KERNEL space. Where transitioning between the two costs extra overhead (because each uses it's own stack). Thread creation is initiated in USER space, but executed in KERNEL space.
30 years ago, you didn't have to deal with security descriptors on memory blocks, which regulate which process has access to which memory block. Where setting up the correct security environment costs extra overhead.
30 years ago, you had less CPU registers. Thus a context switch between two processes took less machine instructions
30 years ago, you didn't have virtual memory to deal with. Setting up new memory blocks takes more overhead now, since you need to setup the paging environment too.
30 years ago, you didn't have execute prevention on data memory blocks. Which also needs extra overhead to setup properly.

This all matters, because each thread you create needs it's own memory block to hold the thread local variables, the stack and a place where the CPU context can be saved when the thread is scheduled out of the CPU.

In short, setting up a new thread to run took less machine cycles 30 years ago, compared to today.
 
  • 2
  • 1
Reactions:

Goshawk

Second Lieutenant
43 Badges
Jul 28, 2017
138
41
  • Crusader Kings III: Royal Edition
  • Hearts of Iron IV: No Step Back
  • Hearts of Iron IV: Colonel
  • Europa Universalis IV: Pre-order
  • Cities: Skylines
The one hour per turn design also exacerbates the lag that players experience. It is so irritating that 10 minutes goes by and not much has happened. I still think the easiest solution is to instruct AI to build 40 width divisions when they pass certain threshold. Or perhaps systems other than combat will be refreshed daily or even weekly insead of hourly.