4

我正在使用 Chapel,并且正在尝试在多bigint语言环境设置中对数组执行计算。读取每行包含一个整数的文件。每行都转换为一条bigint记录,然后插入到单个数组中。我有 4 个语言环境,因此我要求每个语言环境仅读取输入文件的 1/4 并仅处理该部分。

我已将问题减少到以下最小示例,该示例也受到影响:

module Hello {

use BigInteger;
use Math;
use Time;

config const inputPath = "/path/to/file";
config const inputSize = 10000000;
config const power = 2000;

proc dwriteln(args ...?n) {
        var curr = getCurrentTime(unit=TimeUnits.seconds);
        writeln("[ ", here.id, ": ", here.name, " ] [ ", curr, " ] ", (...args));
}

proc main() throws {
    writeln("Input path: ", inputPath);
    writeln("numLocales: ", numLocales);

    var elementsPerLocale = divceil(inputSize, numLocales);
    writeln("elementsPerLocale: ", elementsPerLocale);

    coforall loc in Locales {
        on loc {
            dwriteln("hello");
            var inputFile = open(inputPath, iomode.r, hints=IOHINT_CACHED);
            var reader = inputFile.reader();
            var startI = here.id * elementsPerLocale;
            var endI = startI+elementsPerLocale;
            dwriteln("startI = ", startI, " endI= ", endI);

            var a: [1..0] bigint;
            var i = 0;
            for line in reader.lines() {
                    // i in [startI;endI[
                    if i >= startI && i < endI {
                        a.push_back(new bigint(line, 16));
                    }
                    i +=1;
            }

            reader.close();
            inputFile.close();

            dwriteln("created array of size: ", a.size);

            forall elem in a {
                // perform some computation
                elem = elem ** power;
            }
            dwriteln("Computed.");
        }
    }


}


}

我希望语言环境可以并行执行操作,但事实并非如此。

但是,在运行代码时,似乎每个语言环境都按顺序进行处理。换句话说,语言环境 0 读取文件并进行处理,然后语言环境 1 读取文件并进行处理,依此类推。这可能是什么原因?

4

1 回答 1

0

Chapel 授予并发和并行 I/O 操作:

I/O 概述

A filein Chapel 标识底层操作系统中的文件。对文件的读取和写入是通过与文件关联的一个或多个通道完成的。每个都channel使用一个缓冲区来提供对其文件的顺序读取或写入访问,可选择从偏移量开始。

设计原理

由于通道是独立运行的,因此可以对同一个打开的文件进行并发 I/O,而无需争用锁。此外,由于通道(而不是文件)存储当前文件偏移量,因此可以直接创建并行访问同一个打开文件的程序。请注意,由于 fseek 和 fwrite 之间的竞争条件,当多个线程使用相同的 FILE* 写入文件的不同区域时,这种并行访问在 C 中是不可能的。由于这些问题,希望执行 I/O 的 Chapel 程序员需要知道如何打开文件以及创建通道。

然而,IO模块细节可能有助于更好地安排资源:

据记载,

类型的默认值iohints是未定义的。
...
proc open( out error: syserr, path: string = "", mode: iomode, hints: iohints = IOHINT_NONE, style: iostyle = defaultIOStyle(), url: string = "" ): file

使用非默认的、相当明确的设置重新运行实验,其中 I/O 提示使用 ~ 更好地反映了预期的多语言环境处理IOHINT_PARALLEL

由于for line in reader.lines() {...}ad-hoc 迭代器的性质,也可能有兴趣通过调整IO意图IOHINT_CACHEDIOHINT_SEQUENTIAL设置或openreader() channel特定仪器来查看实验的吞吐量。

iohints 类型的值定义了一组有关文件或通道将执行的 I/O 的提示。实现可以使用这些提示来选择 I/O 操作的优化版本。

iohints类型是实现定义的。 提供了以下 iohints常量:

  *  IOHINT_NONE       defines an empty set, which provides no hints.
  *  IOHINT_RANDOM     suggests to expect random access.
  *  IOHINT_SEQUENTIAL suggests to expect sequential access.
  *  IOHINT_CACHED     suggests that the file data is or should be cached
                       in memory, possibly all at once.
  *  IOHINT_PARALLEL   suggests to expect many channels working with this file
                       in parallel.
于 2017-12-08T15:22:29.330 回答