读取文件到共享内存
Reading files to shared memory
我正在读取一个二进制文件,我想通过 Cilk 和共享内存将其直接卸载到 Xeon Phi。
由于我们每次一次读取相当多的数据和二进制数据,因此首选是使用 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;
}
该示例相对于实际代码非常简化,但足以说明行为。
此代码将 return
ferror: Bad address
Len is 0 and first value of buf is 0
然而,如果我们将 fread 切换为 fgets(不太适合读取二进制数据,特别是 return 值),事情会很好。
那是我们切换 fgets((char *) buf, 2073600, infile);
然后从打印输出中删除 len 我们得到
first value of buf is 46
这符合我们的需要,我可以 运行 _Offload_cilk
以 buf 作为参数的函数并对其进行处理。
有什么东西是我遗漏的吗?或者是 fread 不被支持?我试图从英特尔和互联网上的其他网站找到尽可能多的信息,但遗憾的是我无法做到。
----编辑----
对此进行更多研究后,似乎 运行在共享内存上使用高于 524287(524287 正好是 19 位)的 fread 从上面获取错误。在 524287 或更低的情况下,您可以 运行 任意数量的 fread 并读取所有数据。
我完全找不到为此写的任何理由。
你能试着在 fread 调用之前插入这样的东西吗?
memset(buf, 0, 2073600); // after including string.h
这个技巧对我有用,但我不知道为什么(惰性分配?)。
仅供参考,您还可以 post this forum 上的 MIC 问题。
我没有 PHI,所以看不出这是否会有所不同 -- 但 fread 有它自己的缓冲,虽然对于这种类型的 readind 可能会被关闭,但我不会看看为什么你会经历使用 fread 的开销,而不是仅仅使用较低级别的 open&read 调用,比如
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.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]);
int infile = open(argv[1], O_RDONLY); // should test if open ok, but skip to make code similar to OP's
int len, pos =0, size = 2073600;
buf = (_Cilk_shared uint8_t*) _Offload_shared_malloc(size);
do {
buf[pos]=0; // force the address to be mapped to process memory before read
len = read(infile, &buf[pos], size);
if(len < 0) {
perror("error");
break;
}
pos += len; // move position forward in cases where we have no read the entire data in first read.
size -= len;
} while (size > 0);
printf("Len is %d (%d) and first value of buf is %d\n", len, pos, *buf);
return 0;
}
读写应该与分配的共享内存一起工作,不会出现您所看到的问题。
我正在读取一个二进制文件,我想通过 Cilk 和共享内存将其直接卸载到 Xeon Phi。
由于我们每次一次读取相当多的数据和二进制数据,因此首选是使用 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;
}
该示例相对于实际代码非常简化,但足以说明行为。
此代码将 return
ferror: Bad address
Len is 0 and first value of buf is 0
然而,如果我们将 fread 切换为 fgets(不太适合读取二进制数据,特别是 return 值),事情会很好。
那是我们切换 fgets((char *) buf, 2073600, infile);
然后从打印输出中删除 len 我们得到
first value of buf is 46
这符合我们的需要,我可以 运行 _Offload_cilk
以 buf 作为参数的函数并对其进行处理。
有什么东西是我遗漏的吗?或者是 fread 不被支持?我试图从英特尔和互联网上的其他网站找到尽可能多的信息,但遗憾的是我无法做到。
----编辑----
对此进行更多研究后,似乎 运行在共享内存上使用高于 524287(524287 正好是 19 位)的 fread 从上面获取错误。在 524287 或更低的情况下,您可以 运行 任意数量的 fread 并读取所有数据。
我完全找不到为此写的任何理由。
你能试着在 fread 调用之前插入这样的东西吗?
memset(buf, 0, 2073600); // after including string.h
这个技巧对我有用,但我不知道为什么(惰性分配?)。
仅供参考,您还可以 post this forum 上的 MIC 问题。
我没有 PHI,所以看不出这是否会有所不同 -- 但 fread 有它自己的缓冲,虽然对于这种类型的 readind 可能会被关闭,但我不会看看为什么你会经历使用 fread 的开销,而不是仅仅使用较低级别的 open&read 调用,比如
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.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]);
int infile = open(argv[1], O_RDONLY); // should test if open ok, but skip to make code similar to OP's
int len, pos =0, size = 2073600;
buf = (_Cilk_shared uint8_t*) _Offload_shared_malloc(size);
do {
buf[pos]=0; // force the address to be mapped to process memory before read
len = read(infile, &buf[pos], size);
if(len < 0) {
perror("error");
break;
}
pos += len; // move position forward in cases where we have no read the entire data in first read.
size -= len;
} while (size > 0);
printf("Len is %d (%d) and first value of buf is %d\n", len, pos, *buf);
return 0;
}
读写应该与分配的共享内存一起工作,不会出现您所看到的问题。