MIT6.828_HW6_Threads and Locking

MIT6.828_HW6_Threads and Locking

在此作业中,您将使用哈希表探索使用线程和锁的并行编程。 你应该在具有多个核心的真实计算机(不是xv6,而不是qemu)上完成这项功课。

开的虚拟机只有单CPU单核,所以两个线程与一个线程的程序跑出来是两倍的效果。需要先关闭虚拟机,修改处理器数1,核心数2。再次运行。

./a.out 2
0: put time = 0.007024
1: put time = 0.008762
0: get time = 6.424977
0: 2093 keys missing
1: get time = 6.535123
1: 2093 keys missing
completion time = 6.550038

./a.out 1
0: put time = 0.013344
0: get time = 6.519561
0: 0 keys missing
completion time = 6.533387

两点:1)1个线程完成时间与2个线程的完成时间大致相同,但2个线程操作数量是其两倍; 我们正在实现良好的并行性。 2)2个线程的输出表示 miss 了很多 keys 。 在你的运行中,可能会 miss 更多或更少的keys。如果您使用1个线程运行,则永远不会miss任何keys。

putget中加入互斥。

static 
void put(int key, int value)
{
  
  int i = key % NBUCKET;
  pthread_mutex_lock(&lock);
  insert(key, value, &table[i], table[i]);
  pthread_mutex_unlock(&lock);
  
}
static struct entry*
get(int key)
{
  struct entry *e = 0;
  pthread_mutex_lock(&lock);
  for (e = table[key % NBUCKET]; e != 0; e = e->next) {
    if (e->key == key) break;
  }
  pthread_mutex_unlock(&lock);
  return e;
}

首先阅读一下源码,弄明白为什么会产生missing。

  • keys[]由随机数产生。
  • 对应的线程在put时会将hash table中key值赋值为数组key[]某一段(以2个线程为例,就是0线程赋值为keys[]的前一半),value值置为其线程序号(0,1…等等)。
  • 然后将各个key与value加入对应的桶中(有点像hash的链式解决冲突)。

而在多线程的情况下,当一个线程1进入insert()还未进行插入时,轮转到另一个线程2进行了插入。回到线程1,此时的n还是为空,再进行连接时,就会丢失掉线程2插入的表项。

putget中加入互斥后,再次执行./a.out 2, 确实不会有miss keys的问题了,但是完成时间却上升到15S之久。可见在操作临界区时,多线程带来的效果并不一定会更好,有时反而会更差。

./a.out 2
0: put time = 0.003763
1: put time = 0.014141
0: get time = 15.346588
0: 0 keys missing
1: get time = 15.346687
1: 0 keys missing
completion time = 15.365085

  1. 修改代码,以便在保持正确性的同时并行运行。 (提示:在这个应用程序中,“get”中为确保正确的锁是否必要?)
    基于我们以上的分析,没有必要加入锁,因为其并不修改table。在去除get中的锁后再次执行两个线程程序。完成时间降低到6.0s,并且没有missing。
 ./a.out 2
0: put time = 0.015451
1: put time = 0.016926
0: get time = 5.991161
0: 0 keys missing
1: get time = 5.998054
1: 0 keys missing
completion time = 6.015187

  1. 修改代码,使一些put操作并行运行,同时保持正确性。
    最终put与get代码如下。
static 
void put(int key, int value)
{
  
  int i = key % NBUCKET;
  pthread_mutex_lock(&lock);
  insert(key, value, &table[i], table[i]);
  pthread_mutex_unlock(&lock);
  
}

static struct entry*
get(int key)
{
  struct entry *e = 0;
  for (e = table[key % NBUCKET]; e != 0; e = e->next) {
    if (e->key == key) break;
  }
  return e;
}
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值