[多核并行计算]进程间通信-性能研究

首先介绍下多核并行计算的场景,及测试方法:

(1)并行计算运用在特定大型服务器之上,其硬件水平很高,可能有多几百到上千个cpu。

(2)这些cpu分成了2类,一类是控制cpu,作为主控,用于发起计算,与其他CPU交互,发起计算通知,分析并统计结果等作用;第二类是计算cpu(占大多数)。系统中绝大多数cpu属于计算cpu,因为整个系统就是为了高性能计算。由于计算量大,所以需要很多很多的cpu进行并行计算。每个cpu计算完后,将计算结果传回主控CPU。

(3)系统发起一次计算通知后,每个CPU核心会绑定一个进程开始进行实时运算。不同的CPU上运行着不同的实时进程,计算的通知和计算的结果,需要进程间通信,进行消息传递。并而且要求进程间通信的性能要足够的高,因为当cpu数量上涨到几百上千的时候,进程间通信的性能会影响到整个计算的结果收集。某些实时场景下,系统不允许某一次计算超期完成,这将导致整个业务的失败。

并行计算有知名的MPI库,如果不使用MPI,使用传统方式的linux IPC通信机制,比如管道,信号量,共享内存,消息队列等进程间通信方式。性能会是怎样的呢?下面对这几种IPC通信,进行性能研究。查看每种IPC之间的性能差距,及与MPI库做对比。形成性能分析报告。

首先采用管道方式来进行高性能密集并行计算。 

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h> 
#include <math.h> 
#include <sys/time.h> 
#include <sys/stat.h>

#define SHARE_RFIFO_PATH "/home/rfifo"
#define SHARE_WFIFO_PATH "/home/wfifo"

int    on_cpu;
double dval = 1.23;

int create_process()
{
        int ret;
        pid_t pid;

        pid = fork();
        if(pid < 0) {
                perror("fork");
                return -1;
        }
        if(pid == 0) {

        } else {

        }
        return ret;
}

int gettimeofday(struct timeval *tv, struct timezone *tz);
int do_calc(int loop)
{
        int i;
        for(i=0; i<loop; i++) {
                dval *= sin(3.14159);
        }
}

int do_simulation(int loop_num, int one_loop_num)
{
        int i, count = 0;
        struct timeval tv1, tv2;
        long long us1, us2, ms1, ms2;
        long long ms, us;
        short skip = 2000;
        int max=-1, min = 99999999, val;
        for(i=0; i<loop_num; i++) {
                gettimeofday(&tv1, NULL);
                do_calc(one_loop_num);
                gettimeofday(&tv2, NULL);

                if(--skip < 0) {
                        us1 = (int64_t)tv1.tv_sec*1000*1000 + tv1.tv_usec;
                        us2 = (int64_t)tv2.tv_sec*1000*1000 + tv2.tv_usec;
                        ms1 = (int64_t)tv1.tv_sec*1000 + tv1.tv_usec/1000;
                        ms2 = (int64_t)tv2.tv_sec*1000 + tv2.tv_usec/1000;
                        us = us2 - us1;
                        ms = ms2 - ms1;
                        if(us > max)
                                max = us;
                        if(us < min)
                                min = us;
                        count++;
                        skip = 1000;
                }
        }
        printf("on cpu %d count %d, Jitter %d, max %d, min %d\n", \
                        on_cpu, count, max-min, max, min);
}

int main(int argc, char **argv)
{
        int i, ret = 0;
        int rfd, wfd;
        int len = 0;
        char rbuffer[64], wbuffer[64];

        pid_t pid;

        do_simulation(300000, 20000);
        return 0;

        rfd = mkfifo(SHARE_RFIFO_PATH, O_RDONLY);
        wfd = mkfifo(SHARE_WFIFO_PATH, O_WRONLY);
        if(rfd < 0 || wfd < 0) {
                perror("mkfifo:");
                return rfd|wfd;
        }

        len = read(rfd, rbuffer, sizeof(rbuffer));
        if(len < 0) {
                perror("read:");
                close(rfd);
                close(wfd);
        }




        while(1) sleep(1);
        return ret;
}

猜你喜欢

转载自blog.csdn.net/y33988979/article/details/82430653
今日推荐