我正在阅读一个二进制文件,我希望通过Cilk和共享内存直接将其卸载到Xeon Phi上。
由于我们一次读取相当多的数据,并且二进制数据是首选选项,因此最好使用fread。
因此,如果我制作一个非常简单的示例,它会像这样:
这个例子是从真实代码简化而来的,但足以说明行为。
然后,此代码将返回
然而,如果我们将fread替换为fgets(对于读取二进制数据而言并不是非常适合,特别是返回值方面),那么事情就会变得很好。也就是说,我们将
我是否遗漏了什么或者fread是否不受支持?我已经尝试从英特尔和其他互联网站点找到尽可能多的信息,但遗憾的是我没有找到。
----编辑----
在更深入地研究后,似乎在共享内存上运行fread时,如果值大于524287(524287恰好是19位),则会出现上述错误。 在524287或更低的值下,一切正常,您可以运行任意数量的fread并读取所有数据。
我完全找不到任何原因写在任何地方。
由于我们一次读取相当多的数据,并且二进制数据是首选选项,因此最好使用fread。
因此,如果我制作一个非常简单的示例,它会像这样:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
_Cilk_shared uint8_t* _Cilk_shared buf;
int main(int argc, char **argv) {
printf("Argv is %s\n", argv[1]);
FILE* infile = fopen(argv[1], "rb");
buf = (_Cilk_shared uint8_t*) _Offload_shared_malloc(2073600);
int len = fread(buf, 1, 2073600, infile);
if(ferror(infile)) {
perror("ferror");
}
printf("Len is %d and first value of buf is %d\n", len, *buf);
return 0;
}
这个例子是从真实代码简化而来的,但足以说明行为。
然后,此代码将返回
ferror: Bad address
Len is 0 and first value of buf is 0
然而,如果我们将fread替换为fgets(对于读取二进制数据而言并不是非常适合,特别是返回值方面),那么事情就会变得很好。也就是说,我们将
fgets((char*)buf,2073600,infile)
进行切换,然后从输出中删除len,我们可以得到buf的第一个值为46
,这符合我们的要求,我可以在具有buf作为参数的函数上运行_Offload_cilk
并对其进行处理。我是否遗漏了什么或者fread是否不受支持?我已经尝试从英特尔和其他互联网站点找到尽可能多的信息,但遗憾的是我没有找到。
----编辑----
在更深入地研究后,似乎在共享内存上运行fread时,如果值大于524287(524287恰好是19位),则会出现上述错误。 在524287或更低的值下,一切正常,您可以运行任意数量的fread并读取所有数据。
我完全找不到任何原因写在任何地方。
_Offload_shared_malloc
使用某种延迟评估,那么尝试通过在第一个地址写入单个字节(例如,在read
之前写入*buf = 0;
)来强制映射到进程空间,怎么样? - Sorenerrno
中的特定错误代码以查看是否可以重试某些操作,然后放弃--我编辑了一个最小的循环结构的代码,应该适合你。 - Soren