private void drawState(Brush color, uint lineLen, uint cacheSize, AddrInfo addrInfo, uint setSize = 1) { if (addrInfo == null) { return; } Graphics g = viewPanel.CreateGraphics(); // 현재 정보를 그려줍니다. float y = addrInfo.loc * viewPanel.Height / lineLen; if (addrInfo is SetAddr) { y += ((SetAddr)addrInfo).set * viewPanel.Height / lineLen / setSize; g.FillRectangle(color, 0, y, viewPanel.Width, viewPanel.Height / lineLen / setSize); } else { g.FillRectangle(color, 0, y, viewPanel.Width, viewPanel.Height / lineLen); } g.DrawString(addrInfo.tag.ToString(), Font, Brushes.Black, 0, y); // 나머지 정보를 그려줍니다. g.DrawString("0KB", Font, Brushes.Black, viewPanel.Width - 8 * 3, 0); string size = (cacheSize / 1024).ToString() + "KB"; g.DrawString(size, Font, Brushes.Black, viewPanel.Width - 8 * size.Length, viewPanel.Height - 10); }
// End of Constructor public AddrInfo Load(double locality, int loop = 1) { double totalTime = 0; uint pc = 0; AddrInfo addrInfo; if (cacheType == Type.SetAssociative) { addrInfo = new SetAddr(); } else { addrInfo = new AddrInfo(); } for (int i = 0; i < loop; i++) { if (random.NextDouble() > locality) { pc = randomAddr(); totalTime += Lookup(pc, addrInfo); } else { pc = sequentialAddr(); totalTime += Lookup(pc, addrInfo); } } addrInfo.time = totalTime; return(addrInfo); }
private void button1_Click(object sender, EventArgs e) { // memory uint memSize; if (!uint.TryParse(memSizeText.Text, out memSize)) { ShowToolTip(memSizeText, "메모리 크기를 입력하세요(KB)"); return; } memSize *= 1024; double speed; if (!double.TryParse(speedText.Text, out speed)) { ShowToolTip(speedText, "메모리 속도를 입력하세요(ms)"); return; } Memory mainMem = new Memory(speed); uint wordSize; if (wordCombo.SelectedItem == null || !uint.TryParse( wordCombo.SelectedItem.ToString().Substring(0, 2), out wordSize) ) { ShowToolTip(wordCombo, "메모리 word 길이를 고르세요"); return; } // cache0 uint cacheSize; if (!uint.TryParse(sizeText1.Text, out cacheSize)) { ShowToolTip(sizeText1, "캐시 크기를 입력하세요(KB)"); return; } cacheSize *= 1024; double speed1; if (!double.TryParse(speedText1.Text, out speed1)) { ShowToolTip(speedText1, "캐시 속도를 입력하세요(ms)"); return; } uint lineSize; if (!uint.TryParse(lineSize1.Text, out lineSize)) { ShowToolTip(lineSize1, "라인 크기를 정해주세요(Byte)"); return; } Type t; if (radio1.Checked) { t = Type.Direct; } else if (radio2.Checked) { t = Type.Associative; } else if (radio3.Checked) { t = Type.SetAssociative; } else { ShowToolTip(radio1, "캐시 종류를 골라주세요"); return; } uint setSize = 1; if (t == Type.SetAssociative) { if (!uint.TryParse(setText1.Text, out setSize)) { ShowToolTip(setText1, "Set 크기를 정해주세요(2의 지수)"); return; } } // 초기화 Cache cache0; try { cache0 = new Cache(t, speed1, mainMem, memSize, wordSize, cacheSize, lineSize, setSize); lineLenText1.Text = cache0.lineLength().ToString(); } catch (Exception error) { logText.Text += error.Message; logText.Select(logText.Text.Length, 0); logText.ScrollToCaret(); return; } drawInit(cache0.lineLength(), cacheSize); int loop; if (!int.TryParse(instructionText.Text, out loop)) { ShowToolTip(instructionText, "루프 수를 입력하세요"); return; } double locality = (double)locTrack.Value / 10; logText.Text += string.Format( "Simulation Start({0})\r\n", t); logText.Select(logText.Text.Length, 0); logText.ScrollToCaret(); button1.Enabled = false; button2.Enabled = true; button2.Visible = true; double totalTime = 0; if (verbose) { interrupt = false; new Thread(new ThreadStart( delegate() { AddrInfo prev = null; for (int i = 0; i < loop && !interrupt; i++) { AddrInfo addrInfo = cache0.Load(locality); totalTime += addrInfo.time; Brush brush; switch (addrInfo.state) { case "hit": brush = Brushes.LawnGreen; break; case "compulsory": brush = Brushes.AliceBlue; break; case "conflict": brush = Brushes.Red; break; case "capacity": brush = Brushes.Red; break; default: brush = Brushes.White; break; } drawState(Brushes.AliceBlue, cache0.lineLength(), cacheSize, prev, setSize); drawState(brush, cache0.lineLength(), cacheSize, addrInfo, setSize); prev = addrInfo; Thread.Sleep(100); } //End of for writeLog(cache0, totalTime); } )).Start(); } else { totalTime = cache0.Load(locality, loop).time; writeLog(cache0, totalTime); } }
private double Lookup(uint pc, AddrInfo addrInfo) { // ----------------mem addr---------------- (byte) // ----------------Byte Len--------------<< (cache saved by word) // ----tag Len---(-line Len-------------)<< switch (cacheType) { case Type.Direct: { uint tag = (pc / (wordSize / 8)) / lineLen; uint loc = (pc / (wordSize / 8)) % lineLen; addrInfo.tag = tag; addrInfo.loc = loc; //// Look up // Compulsory if (mem[loc] == null) { compulsory++; addrInfo.state = "compulsory"; mem[loc] = new DirectCache(tag, wordSize); } // Hit or Conflict else { // Hit(Return) if (((BaseBlock)mem[loc]).tag == tag) { hitCount++; addrInfo.state = "hit"; return(speed); } // Conflict else { conflict++; addrInfo.state = "conflict"; ((BaseBlock)mem[loc]).tag = tag; } } // Miss(Loading) if (parent is Cache) { addrInfo.child = new AddrInfo(); return(((Cache)parent).Lookup(pc, addrInfo.child)); } else { return(parent.speed); } } case Type.Associative: { uint tag = (pc / (wordSize / 8)); uint loc = 0; addrInfo.tag = tag; //// Look up // Hit check while (loc < mem.Length && mem[loc] != null) { // Hit(Return) if (((BaseBlock)mem[loc]).tag == tag) { hitCount++; ((AsctvCache)mem[loc]).readOrder = count++; addrInfo.loc = loc; addrInfo.state = "hit"; return(speed); } loc++; } // Conflict(Cache Full) if (lineLen == loc) { capacity++; addrInfo.state = "capacity"; // Victim algorithm loc = victim(); ((AsctvCache)mem[loc]).tag = tag; } // Compulsory else { compulsory++; addrInfo.state = "compulsory"; mem[loc] = new AsctvCache(tag, wordSize); } ((AsctvCache)mem[loc]).readOrder = count++; addrInfo.loc = loc; // Miss(Loading) if (parent is Cache) { addrInfo.child = new AddrInfo(); return(((Cache)parent).Lookup(pc, addrInfo.child)); } else { return(parent.speed); } } case Type.SetAssociative: { uint tag = (pc / (wordSize / 8)) / lineLen; uint loc = (pc / (wordSize / 8)) % lineLen; addrInfo.tag = tag; addrInfo.loc = loc; uint set = 0; //// Look up // Compulsory(set) if (mem[loc] == null) { compulsory++; addrInfo.state = "compulsory"; mem[loc] = new SetAsctvCache(setSize); ((SetAsctvCache)mem[loc]).blocks[set] = new BaseBlock(tag, wordSize); } else { // Hit Check while (set < setSize && ((SetAsctvCache)mem[loc]).blocks[set] != null) { // Hit(Return) if (((SetAsctvCache)mem[loc]).blocks[set].tag == tag) { ((SetAsctvCache)mem[loc]).blocks[set].readOrder = count++; hitCount++; addrInfo.state = "hit"; ((SetAddr)addrInfo).set = set; return(speed); } set++; } // Conflict(Cache Full) if (setSize == set) { conflict++; addrInfo.state = "conflict"; // Victim algorithm set = victim(loc); ((SetAsctvCache)mem[loc]).blocks[set].tag = tag; } // Compulsory(associative) else { compulsory++; addrInfo.state = "compulsory"; ((SetAsctvCache)mem[loc]).blocks[set] = new BaseBlock(tag, wordSize); } } ((SetAsctvCache)mem[loc]).blocks[set].readOrder = count++; ((SetAddr)addrInfo).set = set; // Miss(Loading) if (parent is Cache) { addrInfo.child = new AddrInfo(); return(((Cache)parent).Lookup(pc, addrInfo.child)); } else { return(parent.speed); } } default: throw new Exception("Cache Type Error"); } }