我已经声明了一些全局变量为_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?
发布于 2015-04-18 00:51:02
当一个函数被声明用于卸载时-如果该函数是在该文件中定义的,编译器将生成将在处理器上运行的目标代码和将在协处理器上运行的目标代码。如果该函数在该文件中使用,它将生成将调用处理器版本的目标代码和将调用协处理器版本的代码(除非调用位于受'"ifdef MIC“”保护的区域内
那么,为什么加载器可能希望将一个函数声明为卸载,即使您从未在卸载区域中调用它?好吧,如果函数是类的一部分,那么整个类需要声明为卸载,因为类“知道”哪些函数是它的一部分。当你加载一个类的目标代码时,你就加载了整个类。在这种情况下,如果您要共享该类的对象,则应该将其声明为_Cilk_shared。
如果函数位于动态链接库中,则可能会遇到类似的问题。动态链接库“知道”哪些函数是它的一部分,也“知道”它需要什么函数。因此,当您运行代码时,加载器希望找到库“知道”它需要的所有文件。在这种情况下,最简单的事情就是创建所有库的卸载版本。你可以尝试其他的事情-尝试静态链接包含这些文件的库,或者尝试创建不“知道”他们真正需要的库-将你的库分成几部分,或者尝试显式地创建库的单独主机和协处理器版本,就像你将在协处理器上本机运行的代码一样。
如果这不能解释你所看到的,请告诉我。
https://stackoverflow.com/questions/29671387
复制相似问题