关于 Unified Parallel C 中的指针5
 
- UID
- 1066743
|

关于 Unified Parallel C 中的指针5
清单 12. 数据分布区块大小为有限值的指向共享数据指针与数据分布区块大小为无穷大的指向共享数据指针之间的转换1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
| # include <upc.h>
# include <stdio.h>
# define BLKSIZE 3
# define ARRSIZE 60
# define FAILURE 1
# define SUCCESS 0
# define verify(result,expect) \
{ if ((result)!=(expect)) \
{ \
printf("Error: fail at line %d: mythread=%d, result= %d, expect= %d\n",
__LINE__, MYTHREAD, result,expect); \
upc_global_exit(FAILURE); \
} \
}
shared[] int *p1,arr2[ARRSIZE];
shared[BLKSIZE] int *p2,arr1[ARRSIZE];
int main()
{
int i;
/* initialize array */
upc_forall(i=0;i<ARRSIZE;i++;i)
{
arr1=i;
arr2=-i;
}
upc_barrier;
/* 案例 1:将一个数据分布区块大小为 3 的指向共享数据指针转换为一个数据分布区块大小为无穷大的指向共享数据指针 */
/* 数组 arr1 是一个数据分布区块大小为 3 的共享数组,将其展开如下:
线程 0 线程 1 线程 2 线程 3
0 3 6 9
1 4 7 10
2 5 8 11
// 数组元素 arr1[5] 对应线程 1, 偏移量为 =2*sizeof(int), 相位为 2
12 15 18 21
13 16 19 22
14 17 20 23
...
*/
/*p1 是数据分布区块大小为无穷大的指向共享数据指针 . p1 所对应的线程由对 p1 进行的赋值操作决定,
所以 p1 和数组元素 arr1[5] 对应同一个线程。因为一个数据分布区块大小为无穷大的指向共享数据指针的相位恒为 0,
所以没有必要重新将相位设置为 0. 因此,在强制转换后,p1 将仍然指向 arr1[5]. P1
线程 1
0
1
2
3
4
5
...
*/
p1=(shared[] int *)&arr1[5];
verify(upc_phaseof(p1),0); // 验证 p1 指针在转换后,相位为 0.
verify(upc_threadof(p1),upc_threadof(&arr1[5])); // 验证 p1 指针在转换后,对应的线程不变
verify(*p1,5);
p1++; // 将 p1 指针向前移动一位,将会指向数组元素 arr1[15].
verify(upc_phaseof(p1),0);
verify(upc_threadof(p1),1); // 验证转换后,p1 指针对应的线程和数组元素 arr1[5] 对应的线程一样
verify(*p1,15);
verify(*(p1-3),3); // 验证 p1 指针向后移动 3 位,将会指向数组元素 arr1[3]
/* 案例 2 将一个数据分布区块大小为无穷大的指向共享数据指针转换为一个数据分布区块大小为 3 的指向共享数据指针
*/
/* 数组 arr2 是一个数据分布区块大小为无穷大的共享数组,将其数据分布展开如下。
线程 0 线程 1 线程 2 线程 3
0
1
2
3
4
5 // 数组元素 arr2[5] 对应线程 0, 偏移量为 5*sizeof(int), 相位为 0
6
7
8
9
10
11
12
13
14
15
...
*/
/*p2 是一个数据分布区块大小为 3 的指向共享数据指针,将其展开如下所示。
位置 14 和数组元素 arr2[5] 对应相同的线程,相同的偏移量,但是位置 14 的相位不为 0.
那么就需要将指针 p2 的相位设置为 0,位置 12,位置 13,位置 14 为同一个数据分布区块,
所以位置 12 的相位为 0,所以指针在转换后将指向位置 12,即数组元素 arr2[3] 位置
线程 0 线程 1 线程 2 线程 3
0 3 6 9
1 4 7 10
2 5 8 11
12 15 18 21
13 16 19 22
14 17 20 23
24 27 30 33
25 28 31 34
26 29 32 35
. . .
*/
p2=(shared[BLKSIZE] int *)&arr2[5];
verify(upc_phaseof(p2),0); // 验证转换之后,p2 的相位设为 0
verify(upc_threadof(p2),0); // 验证转换之后,p2 对应的线程和数组元素 arr2[5] 对应的线程一样
verify(*p2,-3); // 验证转换之后,p2 指针将指向数组元素 arr2[3]
p2 -=10; // 将 p2 从 arr2[12] 的位置向后移动 10 位,p2 将指向 arr2[2]
verify(upc_phaseof(p2),2);
verify(upc_threadof(p2),0);
verify(*p2,-2);
return SUCCESS;
}
|
然而,如果任一源指针或者目标指针为指向共享数据通用指针类型,shared void *,结果指针的相位保持不变 , 如清单 13 的例子
清单 13. 将指向共享数据通用指针转换为一个普通指向共享数据指针1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| # include <upc.h> // 假定程序由 3 个线程来运行
# include <stdio.h>
shared void *p1;
shared[3] int arr[10],*p2;
int main()
{
p2=&arr[2]; //p2 指针的相位为 2
p1=&arr[2];
p2=p1; // 在转换之后 p2 指针的相位保持不变
printf("Th:%d,upc_phaseof(p1)=%d,upc_phaseof(p2)=%d\n",MYTHREAD,upc_phaseof(p1),
upc_phaseof(p2));
return 0;
}
|
图 21. 清单 13 程序输出 如果将一个指向共享数据通用指针类型转换为一个指向共享数据非通用指针类型,存在下面两种情况:
如果该指向共享数据非通用类型指针的数据分布区块大小为无穷大或者为 1,结果指针的相位为 0,如清单 14 所示:
清单 14. 结果指针的相位为 01
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| # include <upc.h> // 假定该程序由 3 个线程运行
# include <stdio.h>
shared void *p1;
shared[] int arr1[10],*p2;
shared int arr2[10],*p3;
int main()
{
p2=arr1; // p2 指针的相位为 0
p3=arr2; // p3 指针的相位为 0
p2=p1; // 通用类型指针 p1 转换为非通用类型指针 p2
p3=p1; // 通用类型指针 p1 转换为非通用类型指针 p3
printf("Th:%d,upc_phaseof(p2)=%d,upc_phaseof(p3)=%d\n",MYTHREAD,
upc_phaseof(p2),upc_phaseof(p3));
return 0;
}
|
图 22. 清单程序输出 如果该指向共享数据非通用类型指针的数据区块大小大于 1,而且这个源指针的相位超出目标指针的相位的范围,那么转换结果无意义。 |
|
|
|
|
|