0

我已将一些全局变量声明为 _Cilk_shared。它们用于我要卸载的功能中它们也用于我不想卸载的某些功能中。

所以最初我只将那些需要卸载的函数声明为_Cilk_shared,并使用_Cilk_offload 调用这些函数。

它编译得很好。当我在主机上运行它时,它只会给出正确的结果。

然后我用 MIC 运行它。它给了我关于无法加载库 blablabla 未定义符号的运行时错误,后跟我没有声明为 _cilk_shared 的函数名称。这些函数也不需要 _cilk_shared。

所以我必须把这些函数改成_cilk_shared。再次运行它。这次 MIC 给出了正确的结果。

我检查了这些函数(我不想卸载并且最初没有声明为 _cilk_shared )是否被卸载,通过使用

#ifdef __MIC__
    printf(" Running on MIC\n");
#else
    printf("No MIC\n");
#endif

结果是它们没有被卸载....

所以我想知道为什么它要我将这些函数声明为_Cilk_shared?

4

1 回答 1

0

当一个函数被声明为卸载时 - 如果该函数在该文件中定义,编译器生成将在处理器上运行的目标代码和将在协处理器上运行的目标代码。如果在该文件中使用该函数,它将生成将调用处理器版本的目标代码和将调用协处理器版本的代码(除非调用位于受“ifdef MIC ”保护的区域内

那么,为什么即使您从未在卸载区域中调用该函数,加载程序仍希望将函数声明为卸载呢?好吧,如果函数是类的一部分,则需要声明整个类以进行卸载,因为该类“知道”哪些函数是它的一部分。当您加载一个类的目标代码时,您将加载整个类。在这种情况下,如果您要共享该类的对象,则应将其声明为 _Cilk_shared。

如果函数位于动态链接库中,您可能会遇到类似的问题。动态链接库“知道”它包含哪些功能,并且它“知道”它需要哪些功能。因此,当您运行代码时,加载程序希望找到库“知道”它需要的所有文件。在这种情况下,最简单的方法就是制作所有库的卸载版本。您可以尝试的其他事情 - 尝试静态链接包含这些文件的库或尝试创建不“知道”他们需要他们真正不需要的东西的库 - 将您的库分解或尝试显式创建单独的主机和协处理器版本库,就像您将在协处理器上本地运行的代码一样。

如果这不能解释您所看到的,请告诉我。

于 2015-04-17T16:51:01.507 回答