关闭

Art of Multiprocessor Programming 答案 ch4

标签: 多核无锁
1740人阅读 评论(0) 收藏 举报

大部分答案: 这是一个ps文件

http://www.google.com.hk/url?sa=t&rct=j&q=safe%20M-valued%20MRSW%20register&source=web&cd=1&cad=rja&ved=0CCgQFjAA&url=http%3a%2f%2fwww%2ecs%2enyu%2eedu%2fcourses%2fspring09%2fG22%2e2631-001%2fsol3%2eps&ei=ux2nUr3nGeqIiQfao4DABw&usg=AFQjCNEDFroEyC1U33PCcjc9edCZPyNOTA&bvm=bv.57799294,d.dGI

这是一个在线转换工具:

http://www.docspal.com/



34 ~ 41: 见参考答案

42. 

因为只有一个write重叠,从后往前读。 

case 1: b2 == b1,write已经更新完了;返回b2。

case 2: b2 == b1,write正在更新b0;返回b2。这时write可能已经更新了b[2*N + i]的值,但是原来的值已经记录在b2中,而且是上一次更新的值。

case 2: b2 != b1,write正在更新b1;返回b0。因为只有一个write重叠,所以更新过的b0已经是一个有效值,而且read返回前不会改变。

case 4: b2 != b1,write正在更新b2;返回b0。


从b2到b0读的关键在于,在整个读的过程中只会读到(b2, b1, b0中的)最多一个正在被改变的值。

所以不能从b0往b2读。假如判断是  return (b0 == b1)? b0: b2; 则可能读b2值的时候write正在更新而且没有完成,会返回一个不安全的值。

1 class AcmeRegister implements Register{
2 // N is the total number of threads
3 // Atomic multi-reader single-writer registers
4 private BoolRegister[] b = new BoolMRSWRegister[3 * N];
5 public void write(int x) {
6 boolean[] v = intToBooleanArray(x);
7 // copy v[i] to b[i] in ascending order of i
8 for (int i = 0; i < N; i++)
9 b[i].write(v[i]);
10 // copy v[i] to b[N+i] in ascending order of i
11 for (int i = 0; i < N; i++)
12 b[N+i].write(v[i]);
13 // copy v[i] to b[2N+i] in ascending order of i
14 for (int i = 0; i < N; i++)
15 b[(2*N)+i].write(v[i]);
16 }
17 public int read() {
18	int b2 = booleanArrayToInt(b[2*N], N); //psudo codes
19	int b1 = booleanArrayToInt(b[N], N);
20	int b0 = booleanArrayToInt(b[0], N);
21	
22	return (b2 == b1)? b2: b0;
23 }
24 }



43. True

44. 

Obstruction-Free 实现:

根据题中定理4.5.3, read()中的c0 >= cl; c1 <= cl; 因为 (c0 == c1) ==> (c0 <= cl && c0 >= cl) == > c0 == cl, 即这是一个规则的实现。根据Note:

If a read of c obtains traces of version cj, j >= 0, then:

The beginning of the read preceded the end of write c(j + 1). 

The end of read followed the beginning of the write of cj;

所以如果A不可能读到未来的值,也不会读到过期的值;如果有A.read -> C.read。C只能读到c(j+m)(m>=0)。所以这是一个swmr的原子实现。

class Counter
{
  private boolean c[2][M];
  private int convert(boolean[] c)
  {
    //convert c1c2...cm into counter;
    return 0;
  } 
  
  private boolean[] convert(int v)
  {
    //convert counter value into c array
    return boolean[2];
  }

  public void update(int v)
  {
    boolean[] cv = convert(v);
    for(int i = 0; i < M; i ++)
    {
      c[0][i] = cv[i];
    }
    for(int i = M - 1; i >= 0; i --)
    {
      c[1][i] = cv[i];
    }

    return;
  }

  public int scan()
  {
    boolean  b[2][M];

    do  
    {
      for(int i = M - 1; i >=0; i --)
      {
        b[0][i] = c[0][i];
      }
      for(int i = 0; i < M; i ++)
      {
        b[1][i] = c[1][i];
      }  
    }while(!Arrays.equals(b[0],b[1]);

    return convert(b[0]);
  }
}

Wait-Free 实现

在obstruction-free的证明的基础上。
根据section 4.3中的证明,如果A观察到B udpate了2次,则可以用B的scan作为A scan的结果。因为counter值一直增加,所以如果B保存的值 > A collect一次的值,则B有update,因为根据这个实现,B只有update时才会更新它保存的scan值。

import java.util.*;

public abstract class Counter 
{
	public static final int SIZE = 8;
	public static final int N = 8;
	public ThreadLocal<Integer> ThreadId;
	
	private int[] c1 = new int[SIZE];
	private int[] c2 = new int[SIZE];
	
	private int[] cValueTable = new int[N];
	
	public Counter()
	{
	}
	
	private int[] convert(int value)
	{
		return new int[SIZE];
	}
	
	private int convert(int[] cValue)
	{
		return 0;
	}
	
	public int scan()
	{
		int[] scanC1 = new int[SIZE];
		int[] scanC2 = new int[SIZE];
		boolean[] moved = new boolean[N];
		
		while(true)
		{
			for(int i = 0; i < c1.length; i ++)
			{
				scanC1[i] = c1[i];
			}
			for(int i = c2.length; i >= 0; i --)
			{
				scanC2[i] = c2[i];
			}
			
			int value = convert(scanC1);
			if(Arrays.equals(scanC1, scanC2))
			{
				return value;
			}else
			{
				for(int i = 0; i < N; i ++)
				{
					if(cValueTable[i] > value && moved[i])
					{
						return cValueTable[i];
					}else
					{
						moved[i] =  true;
					}
				}
			}
		}
	}

	
	public void update(int value)
	{
		int me = ThreadId.get().intValue();
	
		int[] cv = convert(value);
		for(int i = c1.length; i >=0; i --)
		{
			c1[i] = cv[i];
		}
		
		for(int i = 0; i < c2.length; i ++)
		{
			c2[i] = cv[i];
		}
		
		cValueTable[me] = value;
	}
}



45.


(1).  因为有W(C2(k)) --> W(C1(k)) --> R(C1(k)) --> R(C2(k))  ==> 即对任意k,读过c1再读c2,得到的c2版本号一定 >= c1的版本号。所以有  l1 < k2。

(2).  令 c(k, l) = c(i1)c(i2)...c(im)。根据4.5.1,有i1 <= i2 <= ... <= im <= l;根据4.5.2有 c(i1)c(i2)...c(im) <= cl。

46. 见参考答案



0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:21986次
    • 积分:385
    • 等级:
    • 排名:千里之外
    • 原创:16篇
    • 转载:0篇
    • 译文:0篇
    • 评论:6条
    最新评论