// Create a new stage object for an instruction with 'id'. private Insn.Stage NewStage(ulong id, int segmentID, string name) { if (segmentID >= m_segments.Count) { for (int i = m_segments.Count; i <= segmentID; i++) { var segment = new Segment(); foreach (var insn in m_insnMap) { segment.stageMap.Add(insn.Key, null); } segment.SegmentID = m_segments.Count; m_segments.Add(segment); } } var stageMap = m_segments[segmentID].stageMap; Insn.Stage oldStage = stageMap[id]; if (oldStage != null) { m_errors.Add( string.Format( "Error: stages {0} and {1} overlap for insnID:{2} at line {3}.", GetStageName(segmentID, oldStage.Id), name, id, m_currentLine ) ); } Insn.Stage newStage = new Insn.Stage(); stageMap[id] = newStage; return(newStage); }
// An instruction exits from a stage. private void ProcessInsnEndStage(string[] cols) { // 0 1 2 3 // field: E id stage segment ulong id = ParseUInt64(cols[1]); Insn insn = GetAliveInsn(id); if (insn == null) { m_errors.Add(string.Format("An unknown instruction ({0}) ends at line {1}.", id, m_currentLine)); return; } int segmentID = (int)ParseUInt64(cols[2]); string stageStr = cols[3]; Insn.Stage stage = GetStage(insn.Id, segmentID, stageStr); stage.EndRelCycle = (Int32)(m_currentCycle - insn.StartCycle); insn.AddStage(segmentID, stage); EndStage(insn.Id, segmentID, stageStr); if (stage == null) { m_errors.Add(string.Format("An unknown stage({0}) is finished at line {1}.", stageStr, m_currentLine)); } }
// Delete a stage object for an instruction with 'id'. private void EndStage(ulong id, int segmentID, string name) { var segment = m_segments[segmentID]; Insn.Stage s = segment.stageMap[id]; Debug.Assert(s.Id == GetStageId(segmentID, name)); segment.stageMap[id] = null; }
// An instruction enters a new stage. private void ProcessInsnBeginStage(string[] cols) { // 0 1 2 3 // field: S id segment stage ulong id = ParseUInt64(cols[1]); Insn insn = GetAliveInsn(id); if (insn == null) { m_errors.Add(string.Format("An unknown instruction ({0}) begins at line {1}.", id, m_currentLine)); return; } int segmentID = (int)ParseUInt64(cols[2]); string stageStr = cols[3]; Insn.Stage stage = NewStage(insn.Id, segmentID, stageStr); stage.Id = GetStageId(segmentID, stageStr); stage.BeginRelCycle = (Int32)(m_currentCycle - insn.StartCycle); }
// Close all unclosed stages. private void CloseStages() { foreach (var segment in m_segments) { var stageMap = segment.stageMap; foreach (ulong id in stageMap.Keys) { Insn.Stage stage = stageMap[id]; if (stage != null) { Insn insn = GetAliveInsn(id); stage.EndRelCycle = (Int32)(m_currentCycle - insn.StartCycle); insn.AddStage(segment.SegmentID, stage); } } } foreach (var insn in m_insnMap.Values) { WriteInsnToDB(insn); } }
private void panelMainView_MouseMove(object sender, MouseEventArgs e) { Point mousePos = new Point(e.X, e.Y); if (lastMousePos == mousePos) { return; } lastMousePos = mousePos; if (panelDragging) { Point p = panelMainView.ScrollPosition; p.Y = p.Y - (e.Y - leftMouseDownPos.Y); p.X = p.X - (e.X - leftMouseDownPos.X); panelMainView.ScrollPosition = p; // Debug.WriteLine(string.Format("({0}, {1})", e.X - lastMousePos.X, e.Y - lastMousePos.Y)); } else { long cycle = coordinateSystem.CycleAtX(e.X) - coordinateSystem.CycleFrom; ulong id = coordinateSystem.InsnIdAtY(e.Y) - coordinateSystem.IdFrom; if (!IsVisibleInsnId(id)) { toolTip.SetToolTip(panelMainView, ""); return; } // マウスオーバー位置のInsnのステージを表示する string stageName = ""; string stageComment = ""; Insn insn = GetInsn(id); if (insn != null) { for (int segmentID = 0; segmentID < insn.StageSegments.Count; segmentID++) { List <Insn.Stage> stages = insn.StageSegments[segmentID]; for (int i = 0; i < stages.Count; i++) { Insn.Stage stage = stages[i]; long beginCycle = insn.StartCycle + stage.BeginRelCycle - coordinateSystem.CycleFrom; long length = (int)stage.Length; if ((beginCycle <= cycle && cycle < beginCycle + length) || (beginCycle == cycle && length == 0)) { if (stageName.Length != 0) { stageName += ", "; } stageName += loginfo.StageNames[segmentID][stage.Id] + "[" + length + "]"; if (stage.Comment != null) { stageComment += stage.Comment; } } } } string tipStr = string.Format("(+{0},+{1}) {2}\n{3}", cycle, id, stageName, stageComment); toolTip.SetToolTip(panelMainView, tipStr); } } }
// Get a stage object from an instruction id. // 'name' is used for validation. private Insn.Stage GetStage(ulong id, int segment, string name) { Insn.Stage s = m_segments[segment].stageMap[id]; Debug.Assert(s.Id == GetStageId(segment, name)); return(s); }
private void DrawDependencyArrow(Graphics g, ulong prodid, ulong consid, int type) { Insn prodinsn = GetInsn(prodid); Insn consinsn = GetInsn(consid); if (prodinsn == null || consinsn == null) { return; } float prodBaseY = coordinateSystem.YAtInsnId(prodid) + CellMarginHeight + coordinateSystem.Cell.Height * 0.5f; float consBaseY = coordinateSystem.YAtInsnId(consid) + CellMarginHeight + coordinateSystem.Cell.Height * 0.5f; float prody = prodBaseY; float consy = consBaseY; if (type >= dependencyArrows.Count) { type = 0; } DependencyArrow arrow = dependencyArrows[type]; Brush dependencyArrowBrush = arrow.brush; Pen dependencyArrowPen = arrow.pen; if (currentViewSetting.DrawDependencyLeftCurve && DrawDependencyLeftCurve) { float prodx = coordinateSystem.XAtCycle(prodinsn.StartCycle); float consx = coordinateSystem.XAtCycle(consinsn.StartCycle); float dy = consy - prody; float left = Math.Min(prodx, consx) - coordinateSystem.Grid.Width; PointF[] pts = new PointF[4]; pts[0] = new PointF(prodx, prody); pts[1] = new PointF(left, prody); pts[2] = new PointF(left, consy); pts[3] = new PointF(consx, consy); DrawArrowhead(g, dependencyArrowBrush, pts[3], new PointF(currentViewSetting.DependencyArrowheadLength, 0), 0.8f); g.DrawBezier(dependencyArrowPen, pts[0], pts[1], pts[2], pts[3]); } if ((currentViewSetting.DrawDependencyInsideCurve && DrawDependencyInsideCurve) || (currentViewSetting.DrawDependencyInsideLine && DrawDependencyInsideLine) ) { float prodx = 0; // prodx, consyが初期化されていないと文句を言われるので…… float consx = 0; // Find an execution stage from a producer and // decide the beginning point of a dependency line. { bool found = false; int prodLane = 0; float prodLaneY = prodBaseY; foreach (var segment in prodinsn.StageSegments) { if (prodLane != 0 && config.DrawInSeparateLane[prodLane]) { prodLaneY += coordinateSystem.Cell.Height; prody = prodLaneY; } else { prody = prodBaseY; } List <Insn.Stage> prodStages = segment; // 0 is a normal stage segment. for (int i = prodStages.Count - 1; i >= 0; i--) { Insn.Stage stage = prodStages[i]; if (IsExecStageId(prodLane, stage.Id)) { prodx = coordinateSystem.XAtCycle(prodinsn.StartCycle + stage.EndRelCycle) - coordinateSystem.Grid.Width * 0.2f; if (stage.Length == 0) { prodx += coordinateSystem.Grid.Width; } found = true; break; } } if (found) { break; } prodLane++; } if (!found) { return; } } // Find an execution stage from a consumer. // decide the end point of a dependency line. { bool found = false; int consLane = 0; float consLaneY = consBaseY; foreach (var segment in consinsn.StageSegments) { if (consLane != 0 && config.DrawInSeparateLane[consLane]) { consLaneY += coordinateSystem.Cell.Height; consy = consLaneY; } else { consy = consBaseY; } List <Insn.Stage> consStages = segment; for (int i = consStages.Count - 1; i >= 0; i--) { Insn.Stage stage = consStages[i]; if (IsExecStageId(consLane, stage.Id)) { consx = coordinateSystem.XAtCycle(consinsn.StartCycle + stage.BeginRelCycle) + coordinateSystem.Grid.Width * 0.2f; found = true; break; } } if (found) { break; } consLane++; } if (!found) { return; } } // Draw a dependency line. if (currentViewSetting.DrawDependencyInsideCurve && DrawDependencyInsideCurve) { float xDiff = (consx - prodx) * 0.6f; float yDiff = 0; { PointF[] pts = new PointF[4]; pts[0] = new PointF(prodx, prody); pts[1] = new PointF(prodx + xDiff, prody + yDiff); pts[2] = new PointF(consx - xDiff, consy - yDiff); pts[3] = new PointF(consx, consy); g.DrawBezier(dependencyArrowPen, pts[0], pts[1], pts[2], pts[3]); } // Draw a dependency arrow head. { PointF arrowVector = new PointF( (consx - prodx) * 3, consy - prody ); float norm = (float)Math.Sqrt(arrowVector.X * arrowVector.X + arrowVector.Y * arrowVector.Y); float f = currentViewSetting.DependencyArrowheadLength / norm; arrowVector.X *= f; arrowVector.Y *= f; DrawArrowhead( g, dependencyArrowBrush, new PointF(consx, consy), arrowVector, 0.8f ); } } if (currentViewSetting.DrawDependencyInsideLine && DrawDependencyInsideLine) { g.DrawLine(dependencyArrowPen, prodx, prody, consx, consy); PointF v = new PointF(consx - prodx, consy - prody); float norm = (float)Math.Sqrt(v.X * v.X + v.Y * v.Y); float f = currentViewSetting.DependencyArrowheadLength / norm; v.X *= f; v.Y *= f; DrawArrowhead(g, dependencyArrowBrush, new PointF(consx, consy), v, 0.8f); } } }