3

我正在读取一个二进制文件,我想通过 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;
}

该示例与真实代码非常简化,但足以举例说明行为。

然后此代码将返回

ferror: Bad address
Len is 0 and first value of buf is 0

但是,如果我们将 fread 换成 fgets (不太适合读取二进制数据,特别是返回值),事情就会很好。

那就是我们切换fgets((char *) buf, 2073600, infile);然后从我们得到的打印输出中删除 len

first value of buf is 46

这符合我们的需要,我可以_Offload_cilk在带有 buf 作为参数的函数上运行并对其进行处理。

有什么我遗漏的东西或者是不支持的吗?我试图从英特尔和互联网上的其他网站上找到尽可能多的信息,但遗憾的是我无法找到。

- - 编辑 - -

在对此进行更多研究之后,似乎在共享内存上运行 fread 并且其值高于 524287(524287 正好是 19 位) fread 会从上面得到错误。在 524287 或更低的情况下,您可以运行任意数量的 fread 并读取所有数据。

我完全找不到任何理由为此写在任何地方。

4

2 回答 2

2

我没有 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;
}

读取和写入应该与分配的共享内存一起使用,而不会出现您看到的问题。

于 2016-05-17T19:20:02.950 回答
1

您可以尝试在 fread 调用之前插入这样的内容吗?

memset(buf, 0, 2073600); // after including string.h

这个技巧对我有用,但我不知道为什么(延迟分配?)。

仅供参考,您也可以在此论坛上发布 MIC 问题。

于 2016-05-17T19:00:33.707 回答