Exemplo n.º 1
0
    def test_tso_write_latency(self):
        """Tests the measurements of write-latency in a TSO cache.

    Write latency is complicated in TSO: writes normally do not add to the cache
    latency, unless they are involved in a write buffer drain. Additionally, any
    write executing when a write buffer drain happens contributes the remainder
    of its cycles to the latency."""

        # Cache with 16 lines, 8 words/line, 4-write buffer with retire-at-2.
        cache = TSOCache(1, 16, 8, self.fake_bus, self.fake_tracker, 4, 2,
                         False)

        # Single write: should be buffered.
        cache.write(5)
        self.assertEqual(cache.latency, 0)

        # A second write: should trip retire at N, but no effect on latency.
        cache.write(10)
        self.assertEqual(cache.latency, 0)
        self.assertEqual(len(cache.write_buffer), 1)

        # Force a drain.
        cache.write(15)  # 2 writes in buffer
        cache.write(20)  # 3 writes in buffer
        cache.write(25)  # 4 writes in buffer; buffer should be full.
        cache.write(30)  # Should force a drain.
        # Latency will be 4 writes in buffer, plus the one that was processing.
        self.assertEqual(cache.latency, 222 * 5)
        self.assertEqual(len(cache.write_buffer), 1)
Exemplo n.º 2
0
  def test_tso_write_latency(self):
    """Tests the measurements of write-latency in a TSO cache.

    Write latency is complicated in TSO: writes normally do not add to the cache
    latency, unless they are involved in a write buffer drain. Additionally, any
    write executing when a write buffer drain happens contributes the remainder
    of its cycles to the latency."""

    # Cache with 16 lines, 8 words/line, 4-write buffer with retire-at-2.
    cache = TSOCache(1, 16, 8, self.fake_bus, self.fake_tracker, 4, 2, False)

    # Single write: should be buffered.
    cache.write(5)
    self.assertEqual(cache.latency, 0)

    # A second write: should trip retire at N, but no effect on latency.
    cache.write(10)
    self.assertEqual(cache.latency, 0)
    self.assertEqual(len(cache.write_buffer), 1)

    # Force a drain.
    cache.write(15) # 2 writes in buffer
    cache.write(20) # 3 writes in buffer
    cache.write(25) # 4 writes in buffer; buffer should be full.
    cache.write(30) # Should force a drain.
    # Latency will be 4 writes in buffer, plus the one that was processing.
    self.assertEqual(cache.latency, 222*5)
    self.assertEqual(len(cache.write_buffer), 1)
Exemplo n.º 3
0
    def test_tso_post_program_drain(self):
        """Test the post-program drain of the write buffer."""

        # Cache with 16 lines, 8 words/line, 4-write buffer with retire-at-2.
        cache = TSOCache(1, 16, 8, self.fake_bus, self.fake_tracker, 4, 2,
                         False)

        # Test that nothing changes if theres nothing in the write buffer.
        cache.latency = 500
        cache.notify_finished()
        self.assertEqual(cache.latency, 500)
        self.assertEqual(cache.write_buffer, [])
        self.assertEqual(cache.write_finishes_at, None)

        # Test that the write buffer is properly cleared if there is something in it.
        cache.latency = 500
        cache.write_buffer = [10, 20]
        cache.write_finishes_at = 505
        cache.notify_finished()
        self.assertEqual(cache.latency, 505 + (2 * 222))
        self.assertEqual(cache.write_buffer, [])
        self.assertEqual(cache.write_finishes_at, None)
Exemplo n.º 4
0
  def test_tso_post_program_drain(self):
    """Test the post-program drain of the write buffer."""

    # Cache with 16 lines, 8 words/line, 4-write buffer with retire-at-2.
    cache = TSOCache(1, 16, 8, self.fake_bus, self.fake_tracker, 4, 2, False)

    # Test that nothing changes if theres nothing in the write buffer.
    cache.latency = 500
    cache.notify_finished()
    self.assertEqual(cache.latency, 500)
    self.assertEqual(cache.write_buffer, [])
    self.assertEqual(cache.write_finishes_at, None)

    # Test that the write buffer is properly cleared if there is something in it.
    cache.latency = 500
    cache.write_buffer = [10, 20]
    cache.write_finishes_at = 505
    cache.notify_finished()
    self.assertEqual(cache.latency, 505 + (2 * 222))
    self.assertEqual(cache.write_buffer, [])
    self.assertEqual(cache.write_finishes_at, None)
Exemplo n.º 5
0
    def test_tso_drain_buffer(self):
        """Tests that the drain buffer logic in the TSO cache is correct."""

        # Cache with 16 lines, 8 words/line, 4-write buffer with retire-at-2.
        cache = TSOCache(1, 16, 8, self.fake_bus, self.fake_tracker, 4, 2,
                         False)

        # Check that draining a cache always clears it completely.
        cache.write_buffer = [1]
        cache._drain_write_buffer()
        self.assertEqual(cache.write_buffer, [])

        cache.write_buffer = [1, 2]
        cache._drain_write_buffer()
        self.assertEqual(cache.write_buffer, [])

        cache.write_buffer = [3, 4, 5, 6, 7]
        cache._drain_write_buffer()
        self.assertEqual(cache.write_buffer, [])

        cache.write_buffer = []
        cache._drain_write_buffer()
        self.assertEqual(cache.write_buffer, [])

        # Check that when the buffer is drained, any ongoing writes are counted as latency.
        cache.write_buffer = []
        cache.latency = 20
        cache.write_finishes_at = 126
        cache._drain_write_buffer()
        self.assertEqual(cache.latency, 126)
        self.assertEqual(cache.write_finishes_at, None)

        cache.write_buffer = [10, 20]
        cache.latency = 20
        cache.write_finishes_at = 126
        cache._drain_write_buffer()
        self.assertEqual(cache.latency, 126 + (2 * 222))
        self.assertEqual(cache.write_finishes_at, None)

        # Check that when the buffer is drained, all writes are counted.
        cache.write_buffer = [10, 20, 30, 40]
        cache.latency = 0
        cache.write_finishes_at = None
        cache._drain_write_buffer()
        self.assertEqual(cache.latency, 4 * 222)
        self.assertEqual(cache.write_finishes_at, None)

        # Check that when drained, writes execute in the correct order.
        cache.write_buffer = [10,
                              138]  # Same slot (1), different tag (0 and 1).
        cache.latency = 0
        cache.write_finishes_at = None
        cache._drain_write_buffer()
        self.assertEqual(cache.latency, 2 * 222)
        self.assertEqual(cache.get_cache_line(1).tag, 1)
        self.assertEqual(cache.get_cache_line(1).state, SlotState.MODIFIED)
Exemplo n.º 6
0
    def test_tso_check_write_buffer(self):
        """Tests that the check-buffer logic in the TSO cache is correct."""

        # Cache with 16 lines, 8 words/line, 4-write buffer with retire-at-2.
        cache = TSOCache(1, 16, 8, self.fake_bus, self.fake_tracker, 4, 2,
                         False)

        # First, check that the method does nothing if a write is still processing.
        cache.write_finishes_at = 15  # Fake a write in progress.
        cache.write_buffer = [10, 5, 20]  # Fake some writes.
        cache._check_write_buffer()
        self.assertEqual(cache.write_finishes_at, 15)
        self.assertEqual(cache.latency, 0)
        self.assertEqual(cache.write_buffer, [10, 5, 20])

        # Check that if a write is not in process but there are less than N (here,
        # 2) writes in the buffer, it still does nothing.
        cache.write_finishes_at = None
        cache.write_buffer = [10]
        cache._check_write_buffer()
        self.assertEqual(cache.write_finishes_at, None)
        self.assertEqual(cache.latency, 0)
        self.assertEqual(cache.write_buffer, [10])

        # Check that if a write is finished and there are less than N (here, 2)
        # writes in the buffer, the write is cleared but thats it.
        cache.write_finishes_at = 10
        cache.latency = 15
        cache.write_buffer = [10]
        cache._check_write_buffer()
        self.assertEqual(cache.write_finishes_at, None)
        self.assertEqual(cache.latency, 15)
        self.assertEqual(cache.write_buffer, [10])

        # Check that if a write is finished and there are N writes in the buffer,
        # another write is retired, from the correct end of the line.
        cache.write_finishes_at = 10
        cache.latency = 15
        cache.write_buffer = [10, 5]
        cache._check_write_buffer()
        self.assertEqual(cache.write_finishes_at, 237)
        self.assertEqual(cache.latency, 15)
        self.assertEqual(cache.write_buffer, [5])

        # Check that if a write is not in progress and there are N writes in the
        # buffer, another write is retired, from the correct end of the line.
        cache.write_finishes_at = None
        cache.latency = 25
        cache.write_buffer = [5, 10]
        cache._check_write_buffer()
        self.assertEqual(cache.write_finishes_at, 247)
        self.assertEqual(cache.latency, 25)
        self.assertEqual(cache.write_buffer, [10])
Exemplo n.º 7
0
    def test_tso_read_latency(self):
        """Tests the measurements of read-latency in a TSO cache."""

        # Cache with 16 lines, 8 words/line, 4-write buffer with retire-at-2.
        cache = TSOCache(1, 16, 8, self.fake_bus, self.fake_tracker, 4, 2,
                         False)

        # First test that write buffers are snooped correctly.
        cache.write(5)
        cache.read(5)
        self.assertEqual(cache.latency, 1)

        cache.latency = 0

        # Test value that is in the L1 cache.
        cache.read(4)  # Prime the cache.
        cache.latency = 0
        cache.read(4)
        self.assertEqual(cache.latency, 3)

        cache.latency = 0

        # Test value returned by other processor.
        cache.read(19)
        self.assertEqual(cache.latency, 23)

        cache.latency = 0

        # Test value returned by main memory.

        # Duck-punch the fake bus to claim that it read from memory.
        # (Don't you love Python? Such abuse! :D)
        old_read_miss = FakeBus.read_miss

        def new_read_miss(self, cache_id, address):
            return True

        FakeBus.read_miss = new_read_miss

        cache.read(26)
        self.assertEqual(cache.latency, 223)

        # Restore the FakeBus class.
        FakeBus.read_miss = old_read_miss
Exemplo n.º 8
0
  def test_tso_drain_buffer(self):
    """Tests that the drain buffer logic in the TSO cache is correct."""

    # Cache with 16 lines, 8 words/line, 4-write buffer with retire-at-2.
    cache = TSOCache(1, 16, 8, self.fake_bus, self.fake_tracker, 4, 2, False)

    # Check that draining a cache always clears it completely.
    cache.write_buffer = [1]
    cache._drain_write_buffer()
    self.assertEqual(cache.write_buffer, [])

    cache.write_buffer = [1, 2]
    cache._drain_write_buffer()
    self.assertEqual(cache.write_buffer, [])

    cache.write_buffer = [3, 4, 5, 6, 7]
    cache._drain_write_buffer()
    self.assertEqual(cache.write_buffer, [])

    cache.write_buffer = []
    cache._drain_write_buffer()
    self.assertEqual(cache.write_buffer, [])

    # Check that when the buffer is drained, any ongoing writes are counted as latency.
    cache.write_buffer = []
    cache.latency = 20
    cache.write_finishes_at = 126
    cache._drain_write_buffer()
    self.assertEqual(cache.latency, 126)
    self.assertEqual(cache.write_finishes_at, None)

    cache.write_buffer = [10, 20]
    cache.latency = 20
    cache.write_finishes_at = 126
    cache._drain_write_buffer()
    self.assertEqual(cache.latency, 126 + (2 * 222))
    self.assertEqual(cache.write_finishes_at, None)

    # Check that when the buffer is drained, all writes are counted.
    cache.write_buffer = [10, 20, 30, 40]
    cache.latency = 0
    cache.write_finishes_at = None
    cache._drain_write_buffer()
    self.assertEqual(cache.latency, 4 * 222)
    self.assertEqual(cache.write_finishes_at, None)

    # Check that when drained, writes execute in the correct order.
    cache.write_buffer = [10, 138] # Same slot (1), different tag (0 and 1).
    cache.latency = 0
    cache.write_finishes_at = None
    cache._drain_write_buffer()
    self.assertEqual(cache.latency, 2 * 222)
    self.assertEqual(cache.get_cache_line(1).tag, 1)
    self.assertEqual(cache.get_cache_line(1).state, SlotState.MODIFIED)
Exemplo n.º 9
0
  def test_tso_check_write_buffer(self):
    """Tests that the check-buffer logic in the TSO cache is correct."""

    # Cache with 16 lines, 8 words/line, 4-write buffer with retire-at-2.
    cache = TSOCache(1, 16, 8, self.fake_bus, self.fake_tracker, 4, 2, False)

    # First, check that the method does nothing if a write is still processing.
    cache.write_finishes_at = 15 # Fake a write in progress.
    cache.write_buffer = [10, 5, 20] # Fake some writes.
    cache._check_write_buffer()
    self.assertEqual(cache.write_finishes_at, 15)
    self.assertEqual(cache.latency, 0)
    self.assertEqual(cache.write_buffer, [10, 5, 20])

    # Check that if a write is not in process but there are less than N (here,
    # 2) writes in the buffer, it still does nothing.
    cache.write_finishes_at = None
    cache.write_buffer = [10]
    cache._check_write_buffer()
    self.assertEqual(cache.write_finishes_at, None)
    self.assertEqual(cache.latency, 0)
    self.assertEqual(cache.write_buffer, [10])

    # Check that if a write is finished and there are less than N (here, 2)
    # writes in the buffer, the write is cleared but thats it.
    cache.write_finishes_at = 10
    cache.latency = 15
    cache.write_buffer = [10]
    cache._check_write_buffer()
    self.assertEqual(cache.write_finishes_at, None)
    self.assertEqual(cache.latency, 15)
    self.assertEqual(cache.write_buffer, [10])

    # Check that if a write is finished and there are N writes in the buffer,
    # another write is retired, from the correct end of the line.
    cache.write_finishes_at = 10
    cache.latency = 15
    cache.write_buffer = [10, 5]
    cache._check_write_buffer()
    self.assertEqual(cache.write_finishes_at, 237)
    self.assertEqual(cache.latency, 15)
    self.assertEqual(cache.write_buffer, [5])

    # Check that if a write is not in progress and there are N writes in the
    # buffer, another write is retired, from the correct end of the line.
    cache.write_finishes_at = None
    cache.latency = 25
    cache.write_buffer = [5, 10]
    cache._check_write_buffer()
    self.assertEqual(cache.write_finishes_at, 247)
    self.assertEqual(cache.latency, 25)
    self.assertEqual(cache.write_buffer, [10])
Exemplo n.º 10
0
  def test_tso_read_latency(self):
    """Tests the measurements of read-latency in a TSO cache."""

    # Cache with 16 lines, 8 words/line, 4-write buffer with retire-at-2.
    cache = TSOCache(1, 16, 8, self.fake_bus, self.fake_tracker, 4, 2, False)

    # First test that write buffers are snooped correctly.
    cache.write(5)
    cache.read(5)
    self.assertEqual(cache.latency, 1)

    cache.latency = 0

    # Test value that is in the L1 cache.
    cache.read(4) # Prime the cache.
    cache.latency = 0
    cache.read(4)
    self.assertEqual(cache.latency, 3)

    cache.latency = 0

    # Test value returned by other processor.
    cache.read(19)
    self.assertEqual(cache.latency, 23)

    cache.latency = 0

    # Test value returned by main memory.

    # Duck-punch the fake bus to claim that it read from memory.
    # (Don't you love Python? Such abuse! :D)
    old_read_miss = FakeBus.read_miss
    def new_read_miss(self, cache_id, address):
        return True
    FakeBus.read_miss = new_read_miss 

    cache.read(26)
    self.assertEqual(cache.latency, 223)

    # Restore the FakeBus class.
    FakeBus.read_miss = old_read_miss