It's mainly the software.
The linux kernel (like most other operating systems) has a interrupt timer than handles the process scheduling of all the processes on the computer.
Until just a few years ago that timer run on 100Hz of historical reasons, wich made process scheduling impossible more often than every 10ms. (ie the absolutley fastest scheduling for an PLC-program would be 10ms)
Now you can choose when you build a custom kernel if you want to run on 100,250 or 1000Hz giving a minimum scheduling time of 1ms.
As far as I know you have to recompile your kernel to change the scheduling speed, and ubuntu probably is running 250Hz by default.
That explained I really think you should consider what speeds you need.
We have a lot of heavy, fast machinery that requires exact movement and posistioning here at SSAB and we rareley need go below 20ms in thread speed in spite of that.
I would say that of around 250 systems we have 2 or 3 running threads on 10ms, and I think 2 of them is dust filters were the cleaning air-pulse length is the critical part.
Also, a modern computer is a bit faster at executing PLC-programs than your average standalone hardware PLC.
So a soft PLC in a PC is a little bit of a tradeoff, maybe you don't get the same scheduling speed for programs as a standalone-PLC, but it can run much larger programs without taking any more time each scheduling cycle, hence giving your more flexibility.
Is there any specific part in your line that you think requires faster scheduling than 20ms and why?
/Ulf