Performance and multithreading

My x64 port of InpOut32
Post Reply
New User
Posts: 2
Joined: Tue Jun 05, 2018 10:30 am

Performance and multithreading

Post by jeroen » Tue Jun 05, 2018 10:33 am


I was wondering about a few things :

- how time-accurate is inpOut32 if I call it EVERY MILLISECOND ? So basically a while(1) loop that sleeps for 1msec and then polls the port.
- what if I even drop the sleep() call and read the port as FAST as possible ? Would this have implications ? What is the max speed I would see port changes ? Basically we are reading a parallel port for a TTL signal and want to respond as fast as possible
- is the code thread safe ? If I have 3 thread that all want to read the port, should I make one extra thread that reads the port and store the result in a volatile variable that the other threads can read ? Or is it safe to just poll from separate thread ?
- occasionally we have a problem where the port seems "stuck" on a value... even though we're 100% sure that the TTL signal changes to low, the port stays stuck on the "high" state (reading on a status bit). It looks like the only solution is to reboot the computer :-( Any suggestions ?
- we read from a PCIe card in a Win7 desktop machine (ASIX card) AND from ANOTHER card (SUNIX). We have the impression that this sometimes could cause the issue above... we've tried using two cards of the same brand (both sunix or both asix) but that made it worse... Is there a brand that you recommend ? Or a setup recommendation about settings in the cards ?

thanks in advance ! I will be prodding my boss for a donation !

User avatar
Site Admin
Posts: 6300
Joined: Sun Apr 06, 2003 11:12 pm

Re: Performance and multithreading

Post by phil » Tue Jun 05, 2018 11:13 am

If you are calling it from user mode (as you will be), then its as accurate as you can be in user mode - but can you be accurate to 1ms? You can only be as accurate as the windows task scheduler will let you be, and you will have to use high precision multimedia timers or the likes as the standard windows timer is not even accurate to 50ms generally.

Then there is the overhead of transitioning from your code (user land) to the driver (kernel land), which will vary depending on the CPU (esp since Spectre/Meltdown as I believe transitions to/from the kernel had to be changed to work around some/one of those issues (making it slower).

As for thread safe... I'm not sure to be honest. I didn't write this, I only ported it to x64 (and havn't looked at the driver code for about 10 years!). The code for the driver is all available (open source) so you could always have a look yourself! But reading only once and remembering will be quicker than reading 3 times (as you will reduce the transitions between userland and kernel by 2) and if things are changing quickly, you may get different values each time you read (which may or may not be what you want).

As for the port getting stuck, I'm afraid I cant help, the last time I used the parallel port directly was back in the DOS days about 22 years ago. Things have moved on a bit since then, but make sure the port is in the correct mode (EPP/ECP/Std) if that still applies. Maybe there are some control codes you can write to the ports control register to reset/unstick it I just don't know. Same goes for hardware recommendations.

Maybe someone else can help there, but don't get your hopes up, this is a *very* quite place these days.

More recently, when I have had any IO to do, it has been using a cheap raspberry pi £13-£35 which has much finer GPIO input/output control down to microsecond accuracy with hardware interrupts... And then I communicate with that from my windows boxes that need to do anything (usually over a web or tcpip interface) - that way there is no issue with Windows and direct hardware access (yay).

And I wouldn't worry about a donation!!! The people that wrote InpOut32 have seemingly disappeared and I am unable to do any further work on it (I don't have the ability to sign drivers as you need an expensive certificate and individuals cant get them, only registered companies) so I've kind'a left this here out of respect for the community. If it stops working there is nothing I can do and if someone does something silly and causes the certificate to be revoked, there will be nothing I can do... So realistically, be ware of using it (of course, if you are a company you could get a driver signing cert and build/sign it yourself going forward so it wouldn't be irreversible, its just not something I can do).
--[ Phil ]--
--[ Administrator & XMBC Author ]--
Logitech G9, Logitech MX518, Microsoft Intellimouse, Trust 16341 BT Mouse
Windows 10 x64, Intel i5-9600k, Asus Z390-ROG, 16GB DDR4,
nVidia GeForce GTX 970, Evo 970 500Gb NVME, 2x2TB WD Black (RAID1)

New User
Posts: 2
Joined: Tue Jun 05, 2018 10:30 am

Re: Performance and multithreading

Post by jeroen » Tue Jun 05, 2018 12:25 pm

yep, I use the performance timer on windows, so time accuracy is okay :-) I do realize that of course i'll have "lost milliseconds" now and then when the scheduler doesn't grant me sufficient slots but I can live with that (and detect+note it by constantly inspecting the clock)

about using a pi or arduino... the problem there is that we have other hardware attached to a DAQ card on the PC, and we need to sync with that too. With a pi/arduino, we get USB transmission delays which are even harder to figure out/measure than TTL :-( usb has a very high throughput but I have no idea how fast I can ping a pi to check for TTL. And as said : we need the TTL-up signal asap to sync it with the DAQ cards (and display stuff on screen + send other outgoing signals on other hardware)

basically this is a software package for psychology experiments and we do a lot of different stuff (google for 'affect 5 psychology software' if you're interested but we're not even in beta at the moment with our new version. The one that is online is outdated)

parallel cards are just so handy for us : pins up & pins down... that's 90% of what we need. And running the whole program on a pi isn't feasible since we need the computer CPU/GPU

anyway : thanks for all the info. I will change the code of my app to poll the parallel ports in ONE place only, and pass that across the threads through some global variables

Post Reply