internal void Run()
        {
            int[]           data       = new int[64];
            EventWaitHandle canLaunch  = new AutoResetEvent(true);
            bool            isLaunch   = false;
            Task            lastRTTask = null;

            while (true)
            {
                CP.StartTrace();
                if (CP.Step(data, out isLaunch))
                {
                    break;
                }
                if (isLaunch)
                {
                    canLaunch.WaitOne();
                    int[] copyData = new int[64];
                    Array.Copy(data, copyData, 64);
                    lastRTTask = Task.Run(() =>
                    {
                        for (int i = 0; i < 64; i++)
                        {
                            int pixelID = copyData[i];
                            RT.ScalarRegisterFile[28] = 0 + RT.DataMemory.Mem.Length / 64 * i; // set Stack Pointer
                            RT.ScalarRegisterFile[29] = RT.ScalarRegisterFile[28].i;
                            RT.ScalarRegisterFile[31] = 0;                                     // set PC
                            RT.ScalarRegisterFile[1]  = pixelID;
                            RunRT(pixelID);
                        }
                        canLaunch.Set();
                    });
                }
                CP.EndTrace();
                if (!disableTrace)
                {
                    foreach (var trace in CP.RegisterFile.TraceLog)
                    {
                        CPOutputFile.Write("R{0} {1} => {2}; ", trace.id, trace.before, trace.after);
                    }
                    foreach (var trace in CP.Memory.TraceLog)
                    {
                        CPOutputFile.Write("{0} {1} => {2}; ", trace.address, trace.before, trace.after);
                    }
                    CPOutputFile.WriteLine();
                }
            }
            lastRTTask?.Wait(); // wait the last launch to complete
        }