模拟一个本地缓存,统计缓存的命中率

为了测试线上服务,加缓存的效果,模拟了一个本地缓存,去测试一下加缓存后的命中率,代码如下:

 

 

import java.util.Date;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 统计任务,统计一下缓存的命中率
 */
public class StatTask {

    public static Log logger = LogFactory.getLog("stat-cache");

    public static AtomicInteger total = new AtomicInteger(0);

    public static AtomicInteger cachedNum = new AtomicInteger(0);

    public static ConcurrentHashMap<String, AtomicInteger> buffer = new ConcurrentHashMap<String, AtomicInteger>();

    public static Executor executor = Executors.newFixedThreadPool(Runtime.getRuntime()
            .availableProcessors() * 2);

    public static void submit(final String url) {
        executor.execute(new Runnable() {

            @Override
            public void run() {
                try {
                    logger.info("link:" + url);
                    if (buffer.containsKey(url)) {
                        int num = buffer.get(url).incrementAndGet();
                        if (num % 10 == 0) {
                            logger.warn(String.format("url:%s be cached %d", url, num));
                        }
                        cachedNum.incrementAndGet();
                    } else {
                        buffer.put(url, new AtomicInteger());
                    }
                    total.incrementAndGet();
                    int cachedNumber = cachedNum.get();
                    int totalNum = total.get();
                    if (cachedNumber > 0 && cachedNumber % 100 == 0) {
                        logger.warn(String.format(
                                "cache hit %d and total:%d, 1.percentage of hits:%s", cachedNumber,
                                totalNum, cachedNumber / (1.0 * totalNum)));
                    }
                } catch (Exception e) {
                    logger.error("统计cache命中率计数器出错:" + e.getMessage());
                }
            }
        });
    }


}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的Cache模拟器,可以模拟Cache不同配置下的命中率: ```python class CacheSimulator: def __init__(self, cache_size, block_size, associativity): self.cache_size = cache_size self.block_size = block_size self.associativity = associativity self.num_blocks = cache_size // block_size self.num_sets = self.num_blocks // associativity self.tag_array = [[None for _ in range(associativity)] for _ in range(self.num_sets)] self.valid_array = [[0 for _ in range(associativity)] for _ in range(self.num_sets)] self.lru_array = [[0 for _ in range(associativity)] for _ in range(self.num_sets)] self.hits = 0 self.misses = 0 def access(self, address): tag, index, offset = self.split_address(address) for i in range(self.associativity): if self.tag_array[index][i] == tag and self.valid_array[index][i] == 1: self.hits += 1 self.update_lru(index, i) return self.misses += 1 for i in range(self.associativity): if self.valid_array[index][i] == 0: self.tag_array[index][i] = tag self.valid_array[index][i] = 1 self.update_lru(index, i) return lru_index = self.get_lru_index(index) self.tag_array[index][lru_index] = tag self.update_lru(index, lru_index) def split_address(self, address): offset_bits = int(math.log(self.block_size, 2)) index_bits = int(math.log(self.num_sets, 2)) tag_bits = 32 - offset_bits - index_bits offset = address & (self.block_size - 1) index = (address >> offset_bits) & (self.num_sets - 1) tag = address >> (offset_bits + index_bits) return tag, index, offset def update_lru(self, index, way): for i in range(self.associativity): if self.lru_array[index][i] < self.lru_array[index][way]: self.lru_array[index][i] += 1 self.lru_array[index][way] = 0 def get_lru_index(self, index): max_lru = max(self.lru_array[index]) for i in range(self.associativity): if self.lru_array[index][i] == max_lru: return i def print_stats(self): total_accesses = self.hits + self.misses hit_rate = self.hits / total_accesses * 100 miss_rate = self.misses / total_accesses * 100 print(f"Cache size: {self.cache_size}") print(f"Block size: {self.block_size}") print(f"Associativity: {self.associativity}") print(f"Total accesses: {total_accesses}") print(f"Hits: {self.hits} ({hit_rate:.2f}%)") print(f"Misses: {self.misses} ({miss_rate:.2f}%)") cache_sizes = [1024, 2048, 4096] block_sizes = [16, 32, 64] associativities = [1, 2, 4] for cache_size in cache_sizes: for block_size in block_sizes: for associativity in associativities: cache = CacheSimulator(cache_size, block_size, associativity) # simulate cache accesses with different workloads # ... cache.print_stats() ``` 在上面的代码中,`CacheSimulator` 类实现了一个 Cache 模拟器,其中 `cache_size`、`block_size`、`associativity` 分别表示 Cache 的大小、块大小和关联度。模拟器使用一个二维数组 `tag_array` 存储缓存中的标记信息,使用一个二维数组 `valid_array` 存储缓存中的有效位信息,使用一个二维数组 `lru_array` 存储缓存中的 LRU 信息。`access` 方法用于模拟 Cache 的读写操作,`split_address` 方法用于将地址分解为标记、索引和偏移量,`update_lru` 方法用于更新 LRU 信息,`get_lru_index` 方法用于获取 LRU 最大的块的索引。最后,`print_stats` 方法用于打印统计信息。 在上面的代码中,我们可以使用三重循环来模拟不同的 Cache 配置,然后调用 `CacheSimulator` 类的方法来模拟 Cache 的读写操作,并打印统计信息。在实际应用中,我们需要根据实际情况选择不同的工作负载数据集,以模拟不同的应用场景。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值