GASNet概述:
最初设计的GASNet主要为支持源到源翻译技术的语言编译器把并行程序转换为使用库的串行代码服务,在实现并行通信的同时凸显了并行语言在其他方面的区别,如UPC中的全局内存分配和锁。由于GASNet是语言无关的,因此翻译的代码通常需要调用指定的运行时库,实现通信的GASNet可以有翻译的代码直接调用或通过特定的运行时库间接调用。因为GASNet最初用于源到源翻译,因此GASNet现在主要用于代码自动生成方面以及未开发并行运行时库的专业程序员提供服务。当性能与易用性发生冲突时, 该设计倾向于选择获得高性能,因此,通常使用C语言的预处理宏对GASNet进行调用。
线程:
GASNet支持客户端使用线程操作且适用于多线程执行,默认情况下,GASNet为各支持网络构建了三个库函数的变体以支持不同的客户端线程模型,其中三个预处理器标记:GASNET_SEQ, GASNET_PARSYNC, GASNET_PAR,必须由客户端顶一切与相应的预处理器标记对应,这三个模型如下:
GASNET_SEQ: 该模式允许客户端在每个进程中使用单线程调用GASNet,且不限制客户端使用的进程数,但必须使用其中一个线程调用全部GASNet。
GASNET_PARSYNC: 该模式最多允许一个线程并发调用GASNet,多线程调用GASNet时可能会引起互斥,而GASNet没有提供这种互斥的机制,因此需要客户端处理。
GASNET_PAR: 这是最常用的模式,支持多个客户端线程并发调用GASNet。
在使用SEQ或PARSYNC模式时,客户端调用GASNet的限制仅局限于客户端上,GASNet使用内部线程是合法的(甚至是在seq编译时), 且这些进程可以用于执行客户端的AM处理程序,因此,无论是线程模式还是其他模式,客户端代码都必须正确使用GASNet的并发控制机制。
API组织:
GASNet的接口分为两组:核心API和扩展API,其中后者主要包括远程内存访问的接口,而其他所有内容都包含在前者中。
开始和结束:
int gasnet_init(int *argcp, char ***argvp);
int gasnet_attach(gasnet_handlerentry_t *table, int numentries, uintptr_t segsize, uintptr_t minheapoffset);
void gasnet_exit(int exitcode);
gasnet_node_t gasnet_nodes(void);
gasnet_node_t gasnet_mynode(void);
char * gasnet_getenv(const char *name);
uintptr_t gasnet_getMaxLocalSegmentSize(void);
uintptr_t gasnet_getMaxGlobalSegmentSize(void);
GASNet客户端通过gasnet_init函数进行初始化,该函数包括引用main()函数的标准参数argc和argv,调用gasnet_init函数的任务环境较为模糊,且不建议用户过多使用任务环境。如果必要的话,请在gasnet_init函数调用前使用,然而当gasnet_init调用后,命令行将清楚GASNet内部使用的所有参数,且环境变量将通过gasnet_getenv获取,此外,初始化函数还设置了任务的stdout和stderr,GASNet不对stdin做任何保证。
只有在gasnet_init函数返回后,上述列表的其他函数才可以合法调用,初始化GASNet任务的下一步将调用gasnet_attach函数以分配GASNet的段(可做远程地址的虚拟地址范围)并保留任务所需的所有网络资源。gasnet_attach的变量赋值给AM处理程序的客户端表,且客户端的段需求如下:
gasnet_handlerentry_t * table;
/* 这是一个指向C结构体数组的指针 */
typedef struct {
gasnet_handler_t index;
void (*fnptr) ();
} gasnet_handlerentry_t;`
fnptr函数作为AM处理程序在相应的整数index上调用,index的128~255范围内的值对客户端都是可用的,而特殊值0表示可以忽略且将由gasnet_attach的特定值重写。
int numentries
表示句柄条目表中条目的个数。
uintptr_t segsize
表示GASNet段的所需大小,其值必须为GASNET_PAGESIZE的倍数,且不大于gasnet_getMaxLocalSegmentSize返回的值。
GASNET_SEGMENT_EVERYTHING可以忽略。
uintptr_t minheapoffset
表示GASNet段与当前堆顶间的最小距离。在包含GASNet段和对空间竞争的虚拟内存系统上,能够确保分配段后还有剩余的空间用于堆分配,虽然不建议使用,但是使用0传递是合法的,且所有节点传递的值都是相等的。由于GASNet段和堆需要竞争同一空间,所以SegmentSize值必须是segsize和minheapoffset之和的最大值,如果客户端找到的可用的段大小小于其要求的大小,则将调用gasnet_exit函数终止任务而不是gasnet_attach函数。
除了两个段大小查询调用与使用gasnet_getenv函数访问环境变量之外,客户端可以调用gasnet_nodes函数查询任务中的GASNet节点数,以及调用gasnet_mynode函数查询当前任务的调用者的进程号。上述调用是gasnet_init和gasnet_attach函数允许调用的全部函数,其中两个段大小查询函数是在gasnet_init和gasnet_attach函数调用时仅有的合法调用函数。
单节点上gasnet_exit函数调用足以使整个并行任务终止,任何没有同时作为一个或者多个调用gasnet_exit函数的节点都有可能返回SIGQUIT信号,这是GASNet方便注册唯一信号处理程序,因为GASNet保留其他所有内容交由内部调用使用,为了避免误触发其机制,客户端在执行正常退出时需要在gasnet_exit函数调用前立即执行同步操作。
段信息: