当前位置: 首页 > 知识库问答 >
问题:

将函数卸载到Intel Xeon Phi所需的时间

戎元忠
2023-03-14

卸载调用将函数的数据(参数)从主机传输到Intel MIC(Xeon Phi协处理器3120系列)是否需要预定义的时间?

具体地说,我对要在mic上执行的函数进行卸载调用(“#pragma offload target(mic)”)。该函数有15个参数(指针和变量),我已经确认了参数在MIC上的正确传递。然而,为了检查参数传递的时间,我简化了代码,因此它只包含一个简单的“printf()”函数。我使用“sys/time.h”头文件的“gettimeofday()”来测量时间,如下代码所示:

主机的一些硬件信息:Intel(R)Core(TM)i7-3770 CPU@3.40GHz/CentOS版本6.8/PCI Express修订版2.0

主. c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include <string.h>

__attribute__ (( target (mic))) unsigned long long ForSolution = 0;
__attribute__ (( target (mic))) unsigned long long sufficientSol = 1;
__attribute__ (( target (mic))) float timer = 0.0;

__attribute__ (( target (mic))) void function(float *grid, float *displ, unsigned long long *li, unsigned long long *repet, float *solution, unsigned long long dim, unsigned long long numOfa, unsigned long long numLoops, unsigned long long numBlock, unsigned long long thread, unsigned long long blockGrid, unsigned long long station, unsigned long long bytesSol, unsigned long long totalSol, volatile unsigned long long *prog);

   float    *grid, *displ, *solution;
   unsigned long long   *li,repet;
   volatile unsigned long long  *prog;
   unsigned long long dim = 10, grid_a = 3, numLoops = 2, numBlock = 0;
   unsigned long long thread = 220, blockGrid = 0, station = 12;
   unsigned long long station_at = 8, bytesSol, totalSol;

   bytesSol = dim*sizeof(float);
   totalSol = ((1024 * 1024 * 1024) / bytesSol) * bytesSol;



   /******** Some memcpy() functions here for the pointers*********/                   



gettimeofday(&start, NULL);

   #pragma offload target(mic) \
        in(grid:length(dim * grid_a * sizeof(float))) \
        in(displ:length(station * station_at * sizeof(float))) \
        in(li:length(dim * sizeof(unsigned long long))) \
        in(repet:length(dim * sizeof(unsigned long long))) \
        out(solution:length(totalSol/sizeof(float))) \
        in(dim,grid_a,numLoops,numBlock,thread,blockGrid,station,bytesSol,totalSol) \
        in(prog:length(sizeof(volatile unsigned long long))) \
        inout(ForSolution,sufficientSol,timer)
   {
        function(grid, displ, li, repet, solution, dim, grid_a, numLoops, numBlock, thread, blockGrid, station, bytesSol, totalSol, prog);
   }

    gettimeofday(&end, NULL);  

    printf("Time to tranfer data on Intel Xeon Phi: %f sec\n", (((end.tv_sec - start.tv_sec) * 1000000.0 + (end.tv_usec - start.tv_usec)) / 1000000.0) - timer);
    printf("Time for calculations: %f sec\n", timer);

作用c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include <string.h>
#include <omp.h>

void function(float *grid, float *displ, unsigned long long *li, unsigned long long *repet, float *solution, unsigned long long dim, unsigned long long numOfa, unsigned long long numLoops, unsigned long long numBlock, unsigned long long thread, unsigned long long blockGrid, unsigned long long station, unsigned long long bytesSol, unsigned long long totalSol, volatile unsigned long long *prog)
{
    struct timeval      timer_start, timer_end;

    gettimeofday(&timer_start, NULL);

printf("Hello World!!!\n");


    gettimeofday(&timer_end, NULL);

    timer = ((timer_end.tv_sec - timer_start.tv_sec) * 1000000.0 + (timer_end.tv_usec - timer_start.tv_usec)) / 1000000.0 ;  
}

终端结果:

Time to tranfer data on Intel Xeon Phi: 3.512706 sec
Time for calculations: 0.000002 sec
Hello World!!!

代码需要3.5秒才能完成“卸载目标”。上述结果正常吗?是否有任何方法可以减少卸载呼叫的显著时间延迟?

共有1个答案

艾学海
2023-03-14

让我们看看这里的步骤:

a)对于第一个#pragma offload,MIC被初始化;这可能包括重置它、启动一个精简的Linux(等待它启动所有CPU、初始化它的内存管理、启动一个psuedo-NIC驱动程序等),并将您的代码上传到设备。这可能需要几秒钟。

b) 所有输入数据均上传至话筒。

c)函数被执行。

d) 所有输出数据都是从麦克风下载的。

对于PCI Express 2.0版(x16)上的原始数据传输,最大带宽为8 GB/s;但是,您无法获得最大带宽。据我所知,与Phi的通信涉及共享的环形缓冲区和“门铃”IRQ,两侧都有“伪NIC”驱动程序(在主机上和协处理器的操作系统上);由于所有的握手和开销,如果你得到的带宽只有最大带宽的一半,我会感到惊讶。

我认为上传的代码、上传的数据和下载的数据总量远远超过1 GiB(例如,out(解决方案:length(totalSol/sizeof(float)))本身就是1 GiB)。如果我们假设“大约4 GiB/s”,那至少还要250 ms。

我的建议是每件事都做两次;测量第一次(包括初始化所有内容)和第二次(所有内容都已经初始化)之间的差异,以确定初始化协处理器需要多长时间。第二次测量(减去执行函数的时间)将告诉您数据传输花费了多长时间。

 类似资料:
  • 函数名称: 卸载应用 函数功能: 卸载一个应用程序 函数方法 app.uninstallApp(bid) 参数 类型 必填 说明 bid string 是 需要卸载的应用包名 函数用例 app.uninstallApp("com.touchsprite.android") 注意事项 如果要卸载的应用在前台或者后台时,无法通过此函数卸载。 目前积木编程函数和触动精灵函数不通用,请仔细查看本手册,此

  • 有人想要代码更为简洁,便把卸载文件代码修改为: Delete "$INSTDIR\*.*" 然后把多余的删除。以前也这样做过,但后来想到,如果某个菜鸟把我们打包的程序安装在了D盘根目录(或其他分区的根目录),而他又点击了卸载的话,真让人欲哭无泪啊——D盘下面的所有文件都没啦! 所以,安装目录中的文件还是老老实实写代码卸载吧。包括桌面上的快捷方式也不要这样卸载,否则卸载后桌面上会空无一物的! 不过

  • 问题内容: 我需要测量程序某些部分所花费的时间(不是用于调试,而是作为输出中的功能)。准确性很重要,因为总时间将不到一秒钟。 当我遇到timeit时,我将使用time模块,该模块声称 避免了一些用于度量执行时间的常见陷阱 。不幸的是,它有一个糟糕的接口,需要一个字符串作为输入,然后才是eval的。 __ 因此,我是否需要使用此模块来准确地测量时间,还是时间足够?它指的是什么陷阱? 谢谢 问题答案:

  • 问题内容: 我需要获取执行时间(以毫秒为单位)。 我最初在2008年问这个问题。当时接受的答案是使用。new Date().getTime()但是,我们大家都可以同意,使用标准performance.now()API更合适。因此,我正在更改对此答案的公认答案。 问题答案: 使用 : NodeJs:需要导入performance类 使用:(非标准)(生活水平)

  • 我试图找到一种方法来告诉一个函数在几秒钟内执行需要多长时间。目前我正在这样做: 但是每次我打印出秒时,它总是显示为-1。我研究了这个问题:经过的时间,但我需要输出以秒为单位。有什么建议吗?

  • 由于install4j没有一个维护安装程序来允许删除部分组件,我修改了卸载程序,以创建显示每个可卸载组件的可配置表单,然后简单地根据用户选择删除文件,这反过来意味着删除标准卸载屏幕。