1

我目前正在使用 X10,并且遇到了多个异常。这是我创建的代码:

主要.x10

public class Main {

// main Method for the Main class
public static def main(argv:Rail[String]) {
    Console.OUT.println("This is the main place. (ID="+here.id+")");
    val dataItem = new Data();
    // no global reference, data is copied to each place.
    finish for (p in Place.places()) {
        at (p) async {
            Console.OUT.println("This is place no: "+here.id+". The value of dataItem is "+dataItem.getValue()+".");
            dataItem.incValue();
        }
    }
    Console.OUT.println("Final value of dataItem without GlobalRef in multiple places at place "+here.id+": "+dataItem.getValue());
    dataItem.setValue(0);
    finish for (p in Place.places()) {
        async {
            Console.OUT.println("This is place no: "+here.id+". The value of dataItem is "+dataItem.getValue()+".");
            dataItem.incValue();
        }
    }
    Console.OUT.println("Final value of dataItem without GlobalRef in one place at place "+here.id+": "+dataItem.getValue());
    dataItem.setValue(0);
    val globalRefDataItem = GlobalRef[Data](dataItem);
    finish for (p in Place.places()) {
        at (p) async {
            val globalDataItemUnwrapped = globalRefDataItem();
            Console.OUT.println("This is place no: "+here.id+". The value of dataItem is "+globalDataItemUnwrapped.getValue()+".");
            atomic globalDataItemUnwrapped.incValue();
        }
    }
    Console.OUT.println("Final value of dataItem with GlobalRef in multiple places at place "+here.id+": "+dataItem.getValue());
}

}

数据.x10

public class Data{
private var value:Long;
def getValue():Long{
    return value;
}
def setValue(value:long){
    this.value = value;
}
def incValue(){
    this.value = this.value+1;
}
}

X10DT 中的输出如下:

This is the main place. (ID=0)
This is place no: 3. The value of dataItem is 0.
This is place no: 1. The value of dataItem is 0.
This is place no: 2. The value of dataItem is 0.
This is place no: 0. The value of dataItem is 0.
Final value of dataItem without GlobalRef in multiple places at place 0: 0
This is place no: 0. The value of dataItem is 0.
This is place no: 0. The value of dataItem is 1.
This is place no: 0. The value of dataItem is 2.
This is place no: 0. The value of dataItem is 3.
Final value of dataItem without GlobalRef in one place at place 0: 4
This is place no: 0. The value of dataItem is 0.
Command used: /home/martze/x10dt/workspace/Example/bin/Main
Uncaught exception at place 0: x10.lang.MultipleExceptions
x10.lang.FailedDynamicCheckException: !(here == x$0.home)
at x10aux::throwException(x10::lang::CheckedThrowable*)
at Main__closure__3::__apply()
at x10::lang::Activity::run()
at x10::lang::Runtime__Worker::loop()
at x10::lang::Runtime__Worker::__apply()
at x10::lang::Runtime__Pool::run()
at 
at GC_inner_start_routine
at GC_call_with_stack_base
at 
at clone
x10.lang.FailedDynamicCheckException: !(here == x$0.home)
at x10aux::throwException(x10::lang::CheckedThrowable*)
at Main__closure__3::__apply()
at x10::lang::Activity::run()
at x10::lang::Runtime__Worker::loop()
at x10::lang::Runtime__Worker::__apply()
at x10::lang::Runtime__Pool::run()
at 
at GC_inner_start_routine
at GC_call_with_stack_base
at 
at clone
x10.lang.FailedDynamicCheckException: !(here == x$0.home)
at x10aux::throwException(x10::lang::CheckedThrowable*)
at Main__closure__3::__apply()
at x10::lang::Activity::run()
at x10::lang::Runtime__Worker::loop()
at x10::lang::Runtime__Worker::__apply()
at x10::lang::Runtime__Pool::run()
at 
at GC_inner_start_routine
at GC_call_with_stack_base
at 
at clone

我尝试使用谷歌搜索,但结果只是指向一些对我没有帮助的文档。我的环境变量设置为 X10_NTHREADS=1,我将位置数设置为 4。我正在使用 Ubuntu,并且正在使用 C++ 后端。

我该怎么办这个错误,这个错误是什么意思?

4

1 回答 1

1

A GlobalRef是对特定位置的对象的全局有意义的引用。它只能在它被创建的地方(“家”的地方)被取消引用。在解引用(“展开”)时引发异常GlobalRef

val globalRefDataItem = GlobalRef[Data](dataItem);
finish for (p in Place.places()) {
  at (p) async {
    val globalDataItemUnwrapped = globalRefDataItem();
    ...
  }
}

GlobalRef是在位置 0 创建的,但在位置被取消引用( globalRefDataItem()) p。如果阅读以下内容,该错误将更容易理解:

x10.lang.FailedDynamicCheckException: (here != globalRefDataItem.home)

要访问 引用的对象,GlobalRef活动必须将位置更改回原位置。例如:

val globalRefDataItem = GlobalRef[Data](dataItem);
finish for (p in Place.places()) {
  at (p) async {
    at(globalRefDataItem.home) {
      atomic globalDataItemUnwrapped.incValue();
    }
  }
}

这通常被称为“乒乓”习语 - 活动更改到远程位置,然后再次更改回原来的位置。

在您的程序中,增加了在 dataItem递增之前打印它的值的要求。为此,请使用at 表达式X10 语言规范§13.3)从远程位置返回一个值,例如:

finish for (p in Place.places()) {
  at (p) async {
    val currentValue = at(globalRefDataItem.home) {
      val globalDataItemUnwrapped = globalRefDataItem();
      var valueBeforeInc:Long = 0;
      atomic {
        valueBeforeInc = globalDataItemUnwrapped.getValue();
        globalDataItemUnwrapped.incValue();
      }
      valueBeforeInc
    };
    Console.OUT.println("This is place no: "+here.id+". The value of dataItem is "+currentValue+".");
  }
}

请注意,我对原始代码进行了重要更改,将值的获取和增量组合在一个atomic块中。如果没有此更改,则另一个活动可能会增加这两个语句之间的值。X10 提供了x10.util.concurrent.AtomicLong提供这种原子getAndIncrement操作的原子类型(例如)。

于 2014-01-19T22:26:59.243 回答