TLS 和 PGAS 有什么区别?

What are the differences between TLS and PGAS?

thread-local storage (TLS) and partitioned global address space (PGAS) 之间的主要区别是什么?使用其中一种语言或程序的含义是什么?

这些方法至少在表面上相似,但实际含义却大不相同。

TLS 是如何指定自动变量(即堆栈上的数据)与操作系统 (OS) 线程(例如 POSIX 线程)相关联,而不是整个 OS进程。

下面是 OpenMP 中的 TLS 示例。我正在使用 OpenMP,因为 GCC 或 Clang 尚不支持 C11 线程。 C11 (C++11) 中的等效语法是 _Thread_local (thread_local).

#include <stdio.h>
#include <stdlib.h>
#include <omp.h>

int p;
#pragma omp threadprivate(p)
int s;

int main(int argc, char **argv)
{
    #pragma omp parallel
    {
        printf("%d: %p %p\n", omp_get_thread_num(), &p, &s );
    }
    return 0;
}

在我的机器上,这段代码的输出是:

> OMP_NUM_THREADS=8 ./tls
1: 0x7fdbb1404ea8 0x1004a5060
2: 0x7fdbb1500c08 0x1004a5060
3: 0x7fdbb1500c18 0x1004a5060
4: 0x7fdbb1500c28 0x1004a5060
5: 0x7fdbb1500c38 0x1004a5060
6: 0x7fdbb1500c48 0x1004a5060
0: 0x7fdbb1500c58 0x1004a5060
7: 0x7fdbb1500c68 0x1004a5060

正如您在这里看到的,每个线程的 TLS 数据地址都不同,而没有 TLS 的全局地址对所有线程都是相同的。

在PGAS中,人们通常假设一个分布式内存系统。默认情况下,数据会私下分配给每个线程(这里的线程可能是 OS 线程、OS 进程或其他线程)。可以根据需要分配共享数据。

下面是一个SHMEM程序。在这个程序中,sheap 数据是每个 PE(处理元素,通常是一个 OS 进程)中的指针,任何其他 PE 都可以使用 shmem_getmemshmem_putmem.

#include <shmem.h>

int main(int argc, char* argv[])
{
    start_pes(0);
    int mype = my_pe();
    int npes = num_pes();

    int n = ( argc>1 ? atoi(argv[1]) : 1000);
    int * sheap = shmalloc(n*sizeof(int));
    if (sheap==NULL) exit(1);
    printf("PE %d: sheap base = %p\n", mype, sheap);
    shfree(sheap);

    return 0;
}

在像 UPC 这样的 PGAS 语言中,可以使用加载-存储语法,但如果数据位于远程位置(远程意味着分布式内存系统中的不同节点),编译器会将这些转换为网络通信函数调用).

TLS 和 PGAS 的根本区别在于,TLS 在线程上下文中工作,其中数据默认 共享 并且 TLS 用于私有化它,而在 PGAS 中,所有数据都是默认私有,共享数据可根据要求分配。

这有帮助吗?我知道 C++11 和 UPC 示例比 OpenMP 和 SHMEM 更有帮助,但后者更容易编写。