X10ファイルIOのベンチマーク
今回はIBM社の並列分散言語であるX10 (http://x10-lang.org/) を使って各種ファイルIO方法を比較して見た。X10を知っている人に対しては当たり前の結果が出ていると思うが、一応地味にやって見たことをポスティングする。
X10は今2.5.4まで出ているらしいが、今回はScaleGraphプロジェクト(http://scalegraph.sourceforge.net/web/) のSX10 2.3.1を使ってやって見た。
今回このバージョンを選んだ理由としては、恥ずかしながらSX10 2.3.1が出た時からやっていた研究がまだあまり進んでいなく、まだSX10 2.3.1を使って研究をしているから。
ベンチマークのやり方
SNAPから拾って来た論文参照関係ネットワークデータ(#Nodes=317,080 / #Edges=85,702,474)において、ファイルIOをテストする。
Read: FileReader VS BufferedReader VS C++ fstream called from x10
Write: Printer VS FileWriter VS C++ ofstream called from x10
C++関数の呼び出しは、以下のブログ文章を参照に作成
x10からC++の関数を呼ぶ
ただ、この記事にはC++関数へ渡す引数として、構造体や配列が扱えるのか、まだX10側でC++関数の結果が参照できるのかは不明だと言っていたが、SX10のソースコードを見ると可能であることがわかった。具体的なやり方は私の他の文章で共有する。
ソースコード
Graph.hpp
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <vector>
#include <map>
using namespace x10::lang;
using namespace x10::io;
using namespace x10aux;
using namespace std;
void writeFile(int size, int* data1);
void readGraphCPP1(const char* file, int maxNode);
Graph.cpp
#include "mycpp.hpp"
void writeFile(int size, int* data1) {
char * filename = "test.bin";
ofstream foutput;
foutput.open(filename, fstream::out | fstream::binary);
for (int i = 0; i < size; ++i) {
foutput.write((char *)(&data1[i]),4);
}
foutput.close();
}
void readGraphCPP1(const char* file, int maxNode) {
ifstream finput;
finput.open(file, fstream::in);
vector<vector<pair<int, double> > > links(maxNode+1);
int nb_links = 0;
double weight = 1.0;
while (!finput.eof()) {
unsigned int src, dst;
finput >> src >> dst;
links[src].push_back(make_pair(dst, weight));
nb_links++;
}
}
BenchInputMain.x10
import x10.io.*;
import x10.compiler.*;
import x10.util.*;
import x10.array.Array;
@NativeCPPInclude("mycpp.hpp")
@NativeCPPCompilationUnit("mycpp.cpp")
public class Test {
private var infile:String = null;
private var maxNode:int = 0;
public def parse_args(args:Array[String]) {
for (var i:int=0; i<args.size; i++) {
if (args(i).equals("-n")) {
maxNode = Int.parse(args(i+1));
}
if (args(i).equals("-i")) {
infile = args(i+1);
}
if (args(i).equals("-o")) {
outfile = args(i+1);
}
}
}
@Native("c++", "readGraphCPP1((#1)->c_str(), #2);")
native static def readGraphCPP1(infile: String, maxNode: int): void;
public def readGraphCPP(){
readGraphCPP1(infile, maxNode);
}
public def readGraphX10() {
val finput = new File(infile);
val links_r = new Array[ArrayList[Pair[int, double]]](maxNode+1);
for (var startIndex :int=0; startIndex<=maxNode; startIndex++) {
links_r(startIndex) = new ArrayList[Pair[int, double]]();
}
var nb_links: int = 0;
val weight = 1.0;
for (line in finput.lines()) {
val src = Int.parse(line.split(" ")(0));
val dest = Int.parse(line.split(" ")(1));
links_r(src).add(new Pair(dest as int, weight as double));
nb_links++;
}
}
public def readGraphBuffX10() {
val finput = new File(infile);
val reader = new BufferedReader(new FileReader(finput));
val links_r = new Array[ArrayList[Pair[int, double]]](maxNode+1);
for (var startIndex :int=0; startIndex<=maxNode; startIndex++) {
links_r(startIndex) = new ArrayList[Pair[int, double]]();
}
var nb_links: int = 0;
val weight = 1.0;
for (line in reader.lines()) {
val src = Int.parse(line.split(" ")(0));
val dest = Int.parse(line.split(" ")(1));
links_r(src).add(new Pair(dest as int, weight as double));
nb_links++;
}
}
public static def main(args: Array[String]) {
val test = new Test();
test.parse_args(args);
Console.OUT.println("Test read file");
for (i in 0..4) {
val t0 = Timer.milliTime();
test.readGraphX10();
Console.OUT.println("Read Graph Time (x10, FileReader): " + (Timer.milliTime()-t0) + "ms");
val t1 = Timer.milliTime();
test.readGraphBuffX10();
Console.OUT.println("Read Graph Time (x10, BufferedReader): " + (Timer.milliTime()-t1) + "ms");
val t2 = Timer.milliTime();
test.readGraphCPP();
Console.OUT.println("Read Graph Time (C++): " + (Timer.milliTime()-t2) + "ms");
}
}
}
BenchOutputMain.x10
import x10.io.*;
import x10.compiler.*;
import x10.util.*;
import x10.array.Array;
@NativeCPPInclude("mycpp.hpp")
@NativeCPPCompilationUnit("mycpp.cpp")
public class Test {
@Native("c++", "writeFile(#1, (#2)->raw()->raw());")
native static def writeFile(size: int, data: Array[int]): void;
public def writeFileWriter(data: Array[int]) {
val filename = "FileWriter.bin";
val w = new x10.io.FileWriter(new File(filename));
for (i in data) {
w.writeInt(data(i));
}
w.close();
}
public def writePrinter(data: Array[int]) {
val filename = "Printer.bin";
val f = new File(filename);
val printer = f.printer();
for (i in data) {
printer.writeInt(data(i));
}
printer.flush();
printer.close();
}
public static def main(args: Array[String]) {
Console.OUT.println("Test write file!!");
val test = new Test();
val size = 100000000;
val data = new Array[int](size, (i: int)=>Random.nextInt());
for (i in 0..4) {
val t0 = Timer.milliTime();
test.writeFileWriter(data);
Console.OUT.println("Write (X10, FileWriter): " + (Timer.milliTime()-t0) + "ms");
val t1 = Timer.milliTime();
test.writePrinter(data);
Console.OUT.println("Write (x10), Printer: " + (Timer.milliTime()-t1) + "ms");
val t2 = Timer.milliTime();
test.writeFile(size, data);
Console.OUT.println("Write (C++): " + (Timer.milliTime()-t2) + "ms");
}
}
}
結果
Test read file!!
Read Graph Time (x10, FileReader): 13854ms
Read Graph Time (x10, BufferedReader): 13620ms
Read Graph Time (C++): 576ms
Read Graph Time (x10, FileReader): 13872ms
Read Graph Time (x10, BufferedReader): 13157ms
Read Graph Time (C++): 465ms
Read Graph Time (x10, FileReader): 13891ms
Read Graph Time (x10, BufferedReader): 13133ms
Read Graph Time (C++): 461ms
Read Graph Time (x10, FileReader): 13930ms
Read Graph Time (x10, BufferedReader): 12974ms
Read Graph Time (C++): 448ms
Read Graph Time (x10, FileReader): 13854ms
Read Graph Time (x10, BufferedReader): 13254ms
Read Graph Time (C++): 508ms
Test write file!!
Write (X10, FileWriter): 25057ms
Write (x10), Printer: 27068ms
Write (C++): 3914ms
Write (X10, FileWriter): 24732ms
Write (x10), Printer: 27039ms
Write (C++): 3818ms
Write (X10, FileWriter): 24905ms
Write (x10), Printer: 27558ms
Write (C++): 3816ms
Write (X10, FileWriter): 24817ms
Write (x10), Printer: 27008ms
Write (C++): 3625ms
Write (X10, FileWriter): 24616ms
Write (x10), Printer: 27984ms
Write (C++): 3533ms
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <vector>
#include <map>
using namespace x10::lang;
using namespace x10::io;
using namespace x10aux;
using namespace std;
void writeFile(int size, int* data1);
void readGraphCPP1(const char* file, int maxNode);
#include "mycpp.hpp"
void writeFile(int size, int* data1) {
char * filename = "test.bin";
ofstream foutput;
foutput.open(filename, fstream::out | fstream::binary);
for (int i = 0; i < size; ++i) {
foutput.write((char *)(&data1[i]),4);
}
foutput.close();
}
void readGraphCPP1(const char* file, int maxNode) {
ifstream finput;
finput.open(file, fstream::in);
vector<vector<pair<int, double> > > links(maxNode+1);
int nb_links = 0;
double weight = 1.0;
while (!finput.eof()) {
unsigned int src, dst;
finput >> src >> dst;
links[src].push_back(make_pair(dst, weight));
nb_links++;
}
}
import x10.io.*;
import x10.compiler.*;
import x10.util.*;
import x10.array.Array;
@NativeCPPInclude("mycpp.hpp")
@NativeCPPCompilationUnit("mycpp.cpp")
public class Test {
private var infile:String = null;
private var maxNode:int = 0;
public def parse_args(args:Array[String]) {
for (var i:int=0; i<args.size; i++) {
if (args(i).equals("-n")) {
maxNode = Int.parse(args(i+1));
}
if (args(i).equals("-i")) {
infile = args(i+1);
}
if (args(i).equals("-o")) {
outfile = args(i+1);
}
}
}
@Native("c++", "readGraphCPP1((#1)->c_str(), #2);")
native static def readGraphCPP1(infile: String, maxNode: int): void;
public def readGraphCPP(){
readGraphCPP1(infile, maxNode);
}
public def readGraphX10() {
val finput = new File(infile);
val links_r = new Array[ArrayList[Pair[int, double]]](maxNode+1);
for (var startIndex :int=0; startIndex<=maxNode; startIndex++) {
links_r(startIndex) = new ArrayList[Pair[int, double]]();
}
var nb_links: int = 0;
val weight = 1.0;
for (line in finput.lines()) {
val src = Int.parse(line.split(" ")(0));
val dest = Int.parse(line.split(" ")(1));
links_r(src).add(new Pair(dest as int, weight as double));
nb_links++;
}
}
public def readGraphBuffX10() {
val finput = new File(infile);
val reader = new BufferedReader(new FileReader(finput));
val links_r = new Array[ArrayList[Pair[int, double]]](maxNode+1);
for (var startIndex :int=0; startIndex<=maxNode; startIndex++) {
links_r(startIndex) = new ArrayList[Pair[int, double]]();
}
var nb_links: int = 0;
val weight = 1.0;
for (line in reader.lines()) {
val src = Int.parse(line.split(" ")(0));
val dest = Int.parse(line.split(" ")(1));
links_r(src).add(new Pair(dest as int, weight as double));
nb_links++;
}
}
public static def main(args: Array[String]) {
val test = new Test();
test.parse_args(args);
Console.OUT.println("Test read file");
for (i in 0..4) {
val t0 = Timer.milliTime();
test.readGraphX10();
Console.OUT.println("Read Graph Time (x10, FileReader): " + (Timer.milliTime()-t0) + "ms");
val t1 = Timer.milliTime();
test.readGraphBuffX10();
Console.OUT.println("Read Graph Time (x10, BufferedReader): " + (Timer.milliTime()-t1) + "ms");
val t2 = Timer.milliTime();
test.readGraphCPP();
Console.OUT.println("Read Graph Time (C++): " + (Timer.milliTime()-t2) + "ms");
}
}
}
import x10.io.*;
import x10.compiler.*;
import x10.util.*;
import x10.array.Array;
@NativeCPPInclude("mycpp.hpp")
@NativeCPPCompilationUnit("mycpp.cpp")
public class Test {
@Native("c++", "writeFile(#1, (#2)->raw()->raw());")
native static def writeFile(size: int, data: Array[int]): void;
public def writeFileWriter(data: Array[int]) {
val filename = "FileWriter.bin";
val w = new x10.io.FileWriter(new File(filename));
for (i in data) {
w.writeInt(data(i));
}
w.close();
}
public def writePrinter(data: Array[int]) {
val filename = "Printer.bin";
val f = new File(filename);
val printer = f.printer();
for (i in data) {
printer.writeInt(data(i));
}
printer.flush();
printer.close();
}
public static def main(args: Array[String]) {
Console.OUT.println("Test write file!!");
val test = new Test();
val size = 100000000;
val data = new Array[int](size, (i: int)=>Random.nextInt());
for (i in 0..4) {
val t0 = Timer.milliTime();
test.writeFileWriter(data);
Console.OUT.println("Write (X10, FileWriter): " + (Timer.milliTime()-t0) + "ms");
val t1 = Timer.milliTime();
test.writePrinter(data);
Console.OUT.println("Write (x10), Printer: " + (Timer.milliTime()-t1) + "ms");
val t2 = Timer.milliTime();
test.writeFile(size, data);
Console.OUT.println("Write (C++): " + (Timer.milliTime()-t2) + "ms");
}
}
}
Test read file!!
Read Graph Time (x10, FileReader): 13854ms
Read Graph Time (x10, BufferedReader): 13620ms
Read Graph Time (C++): 576ms
Read Graph Time (x10, FileReader): 13872ms
Read Graph Time (x10, BufferedReader): 13157ms
Read Graph Time (C++): 465ms
Read Graph Time (x10, FileReader): 13891ms
Read Graph Time (x10, BufferedReader): 13133ms
Read Graph Time (C++): 461ms
Read Graph Time (x10, FileReader): 13930ms
Read Graph Time (x10, BufferedReader): 12974ms
Read Graph Time (C++): 448ms
Read Graph Time (x10, FileReader): 13854ms
Read Graph Time (x10, BufferedReader): 13254ms
Read Graph Time (C++): 508ms
Test write file!!
Write (X10, FileWriter): 25057ms
Write (x10), Printer: 27068ms
Write (C++): 3914ms
Write (X10, FileWriter): 24732ms
Write (x10), Printer: 27039ms
Write (C++): 3818ms
Write (X10, FileWriter): 24905ms
Write (x10), Printer: 27558ms
Write (C++): 3816ms
Write (X10, FileWriter): 24817ms
Write (x10), Printer: 27008ms
Write (C++): 3625ms
Write (X10, FileWriter): 24616ms
Write (x10), Printer: 27984ms
Write (C++): 3533ms
ファイル読み込みにおいて、C++より20倍以上に遅く、ファイル書き込みでは、C++より7倍ぐらい遅くなっている。
Author And Source
この問題について(X10ファイルIOのベンチマーク), 我々は、より多くの情報をここで見つけました https://qiita.com/donaldchi/items/968c008620e7d4e158b1著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .