UPC迅速な研究ノート(2)

統一されたパラレルC - 統一パラレルC言語。並列コンピューティングとプログラミングのためには、C言語の拡張版です。

任意のコンテンツは、ソースを明記してください再現、ありがとうございました。

2.1プログラミングモデル

シングルプロセッサシステム:ノイマンモデル

一般的な並列プログラミングモデル並列プログラミングモデル:メッセージング、メッセージパッシング、共有メモリ、共有メモリ、データ並列のパラレルデータ、及び共有メモリ分散分散共用メモリ。

UPCは、分散共有メモリモデルを使用しています。

 

 がらくたの万語..................最初の3の導入を省略する

このモデルのUPCの使用は、すべてのスレッドが独立しているが、彼らは、共有メモリ空間で動作しています。しかし、彼は、このメモリは、論理的に分割され、(論理的に分割)完全に合計ではありません。そのスレッドが共に同一の物理ノードにマッピングされるデータの部分に分割されます。

ここでは省略万語のこのモデルの利点····································

2.2 UPCのプログラミングモデル

SPMDモードでUPC実行(単一のプログラム、複数のデータストリーム)main()関数を実行する各スレッドは、我々は、コードの実行の各スレッドの制御条件の一部ように、異なるデータストリームを使用します。

UPC標準DSMはまったく同じ、ローカルコンピュータのために、彼は追加のプライベートアドレス空間を持っていません

 

 空間を共有????カジュアルな参照は、自分のプライベートな空間にのみアクセスすることができます。公共、民間、UPCは、アクセスポインタを持っているかどうか

UPCは、複数のスレッドが同じCPUにマッピングすることができます。

プライベート変数と2.3シェア

各スレッド内の1つのインスタンスのプライベートオブジェクトがあります。スレッド0は、すべてのスカラー共有オブジェクトが彼に割り当てられます、非常に特別です。(デフォルトで作成UPCプライベートオブジェクト)

配列の最初の要素は、スレッド0に関連付けられている共有します。

共有変数は、自動保存期間の自動保存期間はありません

無効のfoo(無効
{
shared int x; // not allowed走出大括号}就消失,但又要他共享,矛盾,不允许
static shared int y; // allowed加上静态属性就可以
shared int *p; // allowed私有指针指向共享类型,每个线程有一个私有指针指向共享空间
int *shared q; // not allowed共享指针指向私有变量,在做梦???
...
}

修改为正确的:

shared int x;
int *shared q;
void foo(void)
{
shared int *p;
...
}

2.4共享与私有数组

共享数组的元素以轮转法分配给每个线程

shared int x; /* x is a shared scalar and
will have affinity to thread 0 */
shared int y [THREADS]; /*shared array*/
int z; /*private scalar*/

 

 所以·····这时候看出来为什么之前upc_forall循环里最后一个是i modulo THREADS了吧,这样每个线程每次处理的就是自己对应位置的那一列数据

如果去掉shared,每个线程都有一个自己的大小一样的数组。

高维数组同理

shared int A [4][THREADS];

 

 1 #include <upc_relaxed.h>//upc_relaxed explained in Chapter 6
 2 #define N 10 * THREADS
 3 shared int v1[N], v2[N], v1plusv2[N];
 4 int main ()
 5 {
 6 int i;
 7 upc_forall (i = 0; i < N; i ++; i)
 8 v1plusv2 [i] = v1 [i] + v2 [i];
 9 return 0;
10 }

典型的例子,数组元素以轮转法分布,迭代也以轮转法循环作用于每个线程上。

2.5 Blocked Shared Arrays

 1 #include <upc_relaxed.h>
 2 shared int a [THREADS][THREADS];
 3 shared int b [THREADS], c [THREADS];
 4 int main (void)
 5 {
 6 int i, j;
 7 upc_forall(i = 0; i < THREADS; i++; i)
 8 {
 9 c [i] = 0;
10 for (j= 0; j <THREADS; j++)
11 c [i] += a [i][j]*b [j];
12 }
13 return 0;
14 }

根据以上程序的算法(矩阵乘法),每次计算C[i]时,只有a[i][i]和b[i]是本地操作对象,剩下四个操作数都是远端对象(假设线程数为3)。

默认的共享内存分布模式是可以改变的,只需要给出块大小(block size)也称作blocking factor:

shared [block-size]array [number-of-elements]

如:shared[4] int a[16]

一个16个整型元素的数组,4个4个为一块(block),仍以轮转法分配。一个成块分布的数组的第i个元素与以下线程关联:(i/blocksize)mod THREADS

又如:shared [3] int x [12];

 

 

如果想把所有元素都给thread 0,有以下两种方法:

 

连续块(contiguous blocks)分布:使用*

shared [*] int y[8];

 高维数组同理·······

 1 shared [THREADS] int a[THREADS][THREADS];
 2 shared int b [THREADS], c [THREADS];
 3 int main (void)
 4 {
 5 int i, j;
 6 upc_forall(i = 0; i < THREADS; i++; i)
 7 {
 8 c [i] = 0;
 9 for (j= 0; j (THREADS; j++)
10 c [i] += a [i][j]*b [j];
11 }
12 return 0;

唯一的区别在于,数组a被块大小THREADS限制,也就是说,块大小等于总线程数

之前:

 

现在:

 

 计算c[i]只需要一次远程访问(remote access),比之前的四次大大减少

2.6 共享内存在不同编译环境下要注意的地方

在编译时给出线程数是推荐的,称作static THREADS;否则称dynamic THREADS

虽然运行时给出线程数会很方便,但对编译器来说会出现问题,因为给每个线程分配的数组元素数取决于线程数量。故而dynamic THREADS 环境下声明数组是非法的。

以下在两种情况下均正确:

shared int x [10*THREADS];
shared [] int x [10];

以下在动态情况下非法:

shared int x [10];
shared [] int x [THREADS];
shared int x [10+THREADS];

2.7 总结

 

 注:

本系列所有内容均来自《UPC: Distributed Shared Memory Programming》。这些文章是为了期中考试临时抱佛脚的结果···若有谬误,敬请指教。

All contents in this article are from <UPC: Distributed Shared Memory Programming>, if this has violated your copyright, contact me immediately at [email protected]. Thank you.

おすすめ

転載: www.cnblogs.com/mrlonely2018/p/11701564.html