Qt-interest Archive, March 2008
Multithreaded problem
Message 1 in thread
Hey all,
I'm having a little multithread problem.
Here's the problem:
I am working on an emulator for a 6809, emulating the CPU itself is pretty easy and not a problem. However, the emulator i'm working on doesn't just have to emulate the CPU, it also has to emulate other peripheral hardware that is attached that the CPU interacts with. Now unfortunately the timings of certain signals from the peripherals are relatively critical. They have to come in the right order and at the right time with respect to the program flow or else things do not work correctly.
This is where all the standard CPU emulation approaches fail as they usually only worry about the CPU and no peripheral hardware and don't worry so much about cycle time. That's fine without interdependencies but in my case, fails miserably.
Now to remedy this problem, I thought I'd do a more accurate simulation by giving each component that is being simulated it's own thread and, just like in the real hardware, driving all components using one common clock signal.
With such a multi-threaded approach I could technically do something like this;
void Processor::myInstruction()
{
// Code for step 1
waitForCycle();
// Code for step 2
waitForCycle();
// Code for step 3
waitForCycle();
}
Without the CPU being on it's own thread, I'd need a pretty messy state machine to do the same thing.
So far so good, here is where the problem comes in.
I tried using QWaitConditions at first inside the waitForCycle. Basically when entering the wait function, the wait condition would wait to be woken up and then the function could resume execution.
This worked but speed-wise was way too slow. I got an effective frequency of 0.2MHz which is a bit too slow even for a 1MHz CPU. :)
Then I tried to use a QMutex instead but that didn't work out all that well either.
Anyone have any suggestions for this kind of problem? Basically I need a way to pause and start multiple threads roughly a million times per second. :)
Thanks,
Stephan
Message 2 in thread
kermos@xxxxxxxxxx wrote:
>
> Anyone have any suggestions for this kind of problem?
> Basically I need a way to pause and start multiple
> threads roughly a million times per second. :)
Given that the granularity of QTimer is at best 1ms,
this doesn't seem to be feasible to me.
How are you generating your simulated clock ?
--
[ signature omitted ]
Message 3 in thread
I think this is not a problem of QT. You need a real-time OS. (exact timing
of thread. Fast job interchange.etc.)
Neither Linux nor Windows is not a real-time OS. (Some special type of Linux
can do real-time operation)
So, as I know, the exact timing with threads is not guaranteed.
If this is essential for you, you can search the internet real-time version
of Linux.
(I have no idea Qt is available on that Linux version)
Sam.
P.S.:
Also, if the signal timing is critical, It can be affected by wiring.
So even if you succeeded to emulate CPU, it can be different to real
hardware implementation.
That's the common difficulty of the circuit emulators.
I think it's better you ask to hardware designer to guarantee some
prioritized operations.
Unless, your job is hard and the application developer will also have same
problem.
Confusing timing leads the developers to throw out the CPU.
From: kermos@xxxxxxxxxx [mailto:kermos@xxxxxxxxxx]
Sent: Friday, March 14, 2008 11:43 AM
To: qt-interest@xxxxxxxxxxxxx
Subject: Multithreaded problem
Hey all,
I'm having a little multithread problem.
Here's the problem:
I am working on an emulator for a 6809, emulating the CPU itself is pretty
easy and not a problem. However, the emulator i'm working on doesn't just
have to emulate the CPU, it also has to emulate other peripheral hardware
that is attached that the CPU interacts with. Now unfortunately the timings
of certain signals from the peripherals are relatively critical. They have
to come in the right order and at the right time with respect to the program
flow or else things do not work correctly.
This is where all the standard CPU emulation approaches fail as they usually
only worry about the CPU and no peripheral hardware and don't worry so much
about cycle time. That's fine without interdependencies but in my case,
fails miserably.
Now to remedy this problem, I thought I'd do a more accurate simulation by
giving each component that is being simulated it's own thread and, just like
in the real hardware, driving all components using one common clock signal.
With such a multi-threaded approach I could technically do something like
this;
void Processor::myInstruction()
{
// Code for step 1
waitForCycle();
// Code for step 2
waitForCycle();
// Code for step 3
waitForCycle();
}
Without the CPU being on it's own thread, I'd need a pretty messy state
machine to do the same thing.
So far so good, here is where the problem comes in.
I tried using QWaitConditions at first inside the waitForCycle. Basically
when entering the wait function, the wait condition would wait to be woken
up and then the function could resume execution.
This worked but speed-wise was way too slow. I got an effective frequency of
0.2MHz which is a bit too slow even for a 1MHz CPU. :)
Then I tried to use a QMutex instead but that didn't work out all that well
either.
Anyone have any suggestions for this kind of problem? Basically I need a way
to pause and start multiple threads roughly a million times per second. :)
Thanks,
Stephan
Message 4 in thread
-------- Original Message --------
> From: Stephen Collyer
> Sent: Friday, March 14, 2008 12:02 PM
> To: qt-interest@xxxxxxxxxxxxx
> Subject: Re: Multithreaded problem
>
> kermos@xxxxxxxxxx wrote:
> >
> > Anyone have any suggestions for this kind of problem?
> > Basically I need a way to pause and start multiple
> > threads roughly a million times per second. :)
>
> Given that the granularity of QTimer is at best 1ms,
> this doesn't seem to be feasible to me.
>
> How are you generating your simulated clock ?
Well the global emulator itself runs on it's own thread. That's what provides the clock for everything else.
Since I can't use a timer for it as you have correctly stated, this is what I do:
I take my clock frequency and divide it by 16 and then run the CPU for that # of cycles 16 times a second.
Then using a timing function that is capable of timing code with up to 1us precision, I get the elapsed time between the start of the cycles and the end of the cycles. 16 frames per second gives me 62.5ms per frame, so I subtract my elapsed time from 62.5 and then put the thread to sleep for that many milliseconds.
Rinse and repeat for as long as the emulation runs.
This works very well for giving me exactly the frequency I want and I can make the burst granularity finer if I want. The bursts don't affect the emulated devices are still synchronized to one another as they are all being driven by the same clock.
But the issue is that the threads that the device run on do need to be started / stopped once for each cycle during these bursts..
Currently I came up with a solution that works, but CPU usage on it is very very high. Basically I'm just using a volatile variable now that's set to 1 during cycle execution and 0 during wait for next cycle. Then the main emulator resets the value to 1 signaling the wait for next cycle that it can exit. This works....but CPU usage goes through the roof. I'm going to have to see if I can put all the device threads to sleep along with the main emulation thread while it performs its sleep during the non-burst periods.
Thanks,
Stephan
--
[ signature omitted ]