我正在使用MIPS模拟器作为学习项目。为了获得所需的性能,我希望每个处理器始终在自己的线程中休眠,并且当DMA传输发生时,它们开始处理。
之前我使用过BackgroundWorker,刚刚开始使用async / away指令,我读过有关线程池的内容。 "记忆空间"将被共享,因此DMA状态位是"自然"锁定机制。这些线程技术似乎没有做我想做的事情。我错过了什么?
也许这个代码示例(编译,不起作用)将解释我的想法。
public class ThreadingEmulatorCode
{
static Memory memory = new Memory();
public ThreadingEmulatorCode()
{
CPU cpu = new CPU();
memory.OnDMAZero += cpu.zero.Execute(new DMAEventArgs());
memory.OnDMAOne += cpu.one.Execute(new DMAEventArgs());
cpu.Run(ref memory);
}
}
public delegate void dmazero(DMAEventArgs args);
public delegate void dmaone(DMAEventArgs args);
public class DMAEventArgs : EventArgs
{
public byte[] Data { get; set; }
public uint Address { get; set; }
}
public class Memory
{
public event dmazero OnDMAZero;
public event dmaone OnDMAOne;
private const uint CoprocZeroDMA = 0x1FC00000;
private const uint CoprocOneDMA = 0xBFC00000;
private byte[] memory;
public Memory()
{
this.memory = new byte[(8 * 1024 * 1024)];
}
public byte this[uint address]
{
get
{
return memory[address];
}
set
{
memory[address] = value;
if (address == CoprocZeroDMA && OnDMAZero != null)
OnDMAZero(new DMAEventArgs());
if (address == CoprocOneDMA && OnDMAOne != null)
OnDMAOne(new DMAEventArgs());
}
}
}
public class CPU
{
public CoprocZero zero;
public CoprocOne one;
public void Run(ref Memory memory)
{
/* Start Executing Instructions */
}
public CPU()
{
zero = new CoprocZero();
one = new CoprocOne();
}
}
public class CoprocZero
{
public CoprocZero(/* Start Listening Thread */) { }
public dmazero Execute(DMAEventArgs dmaEvent)
{
/* Process DMA'd Data */
throw new NotImplementedException();
}
}
public class CoprocOne
{
public CoprocOne(/* Start Listening Thread */) { }
public dmaone Execute(DMAEventArgs dmaEvent)
{
/* Process DMA'd Data */
throw new NotImplementedException();
}
}
想法或建议?感谢。
答案 0 :(得分:0)
看起来我只需要花更多时间在代码上。抱歉。我最初期望在TryPeek上的紧张时间最大CPU,但它在进程列表中位于零CPU。我还没有验证总体性能,但我认为这样可行。
// Code to Test
// ThreadingExampleCode stackOverflow = new ThreadingExampleCode();
// Thread.Sleep(new TimeSpan(1, 0, 0));
public class ThreadingExampleCode
{
public static Memory memory;
private CoprocZero zero;
private CoprocOne one;
private CPU cpu;
private Thread coprocZero;
private Thread coprocOne;
ConcurrentQueue<uint> coprocZeroQueue = new ConcurrentQueue<uint>();
ConcurrentQueue<uint> coprocOneQueue = new ConcurrentQueue<uint>();
public ThreadingExampleCode()
{
memory = new Memory();
memory.OnDMAZero += MemoryOnOnDmaZero;
memory.OnDMAOne += MemoryOnOnDmaOne;
cpu = new CPU(memory);
zero = new CoprocZero(memory, coprocZeroQueue);
one = new CoprocOne(memory, coprocOneQueue);
coprocZero = new Thread(zero.RunParm);
coprocZero.Start();
coprocOne = new Thread(one.RunParm);
coprocOne.Start();
cpu.Run();
}
private void MemoryOnOnDmaOne(DMAEventArgs args)
{
coprocOneQueue.Enqueue(args.Address);
}
private void MemoryOnOnDmaZero(DMAEventArgs args)
{
coprocZeroQueue.Enqueue(args.Address);
}
}
public delegate void dmazero(DMAEventArgs args);
public delegate void dmaone(DMAEventArgs args);
public class DMAEventArgs : EventArgs
{
public uint Address { get; set; }
}
public class Memory
{
public event dmazero OnDMAZero;
public event dmaone OnDMAOne;
public const uint CoprocZeroDMA = 1 * 1024 * 1024;
public const uint CoprocOneDMA = 2 * 1024 * 1024;
private byte[] memory;
public Memory()
{
this.memory = new byte[(8 * 1024 * 1024)];
}
public byte this[uint address]
{
get { return memory[address]; }
set
{
memory[address] = value;
if (address == CoprocZeroDMA && OnDMAZero != null)
OnDMAZero(new DMAEventArgs());
if (address == CoprocOneDMA && OnDMAOne != null)
OnDMAOne(new DMAEventArgs());
}
}
}
public class CPU
{
private Memory memory;
public CPU(Memory inMemory)
{
memory = inMemory;
}
public void Run()
{
/* Start Executing Instructions */
memory[Memory.CoprocZeroDMA] = 0x01;
memory[Memory.CoprocOneDMA] = 0x01;
}
}
public class CoprocZero
{
private ConcurrentQueue<uint> queueToMonitor;
private Memory memory;
public CoprocZero(Memory inMemory, ConcurrentQueue<uint> queue)
{
memory = inMemory;
queueToMonitor = queue;
}
public void RunParm()
{
uint memoryAddress;
while (!queueToMonitor.TryPeek(out memoryAddress)) { };
if (queueToMonitor.TryDequeue(out memoryAddress))
{
Debugger.Break();
}
}
}
public class CoprocOne
{
private Memory memory;
private ConcurrentQueue<uint> queueToMonitor;
public CoprocOne(Memory inMemory, ConcurrentQueue<uint> queue)
{
memory = inMemory;
queueToMonitor = queue;
}
public void RunParm()
{
uint memoryAddress;
while (!queueToMonitor.TryPeek(out memoryAddress)) { };
if (queueToMonitor.TryDequeue(out memoryAddress))
{
Debugger.Break();
}
}
}