如何修复 Java 中的可调用重叠?
How can I fix callable overlapping in Java?
我不确定标题是不是detail/correct但是我不知道如何在标题中描述它所以我会尽力在这里描述它
我一直在尝试在 Java 中使用 callable 进行并发,但结果不正确,似乎线程已经相互重叠,而 运行...下面是
的调用函数
@Override
public String call() {
String result = "yay";
long startTime = System.currentTimeMillis();
long endTime = startTime + timeOutMiliseconds * 1000;
while (System.currentTimeMillis() < endTime) {
int[] currentMapping = generateTpuMappingWithRange(ia, startRange, stopRange);
System.out.println(" current - " + Arrays.toString(currentMapping) + " - " + ID);
result = Arrays.toString(currentMapping);
}
return result;
}
generateTpuMappingWithRange()
函数只是生成另一个随机整数数组,第一个索引来自 startRange -> stopRange
(即 startRange = 0,stopRange = 2,然后 [0, 2, 1,] -> [1, 2, 1] 或 [2,2,1])
构造函数
public MarkovTest(int ID, int startRange, int stopRange) {
this.ID = ID;
this.startRange = startRange;
this.stopRange = stopRange;
init();
}
这是主要内容
public static void main(String[] args) throws InterruptedException, ExecutionException {
Callable<String> Array = new MarkovTest(1, 0, 1);
Callable<String> Array2 = new MarkovTest(2, 2, 3);
Callable<String> Array3 = new MarkovTest(3, 4, 5);
List<Callable<String>> taskList = Arrays.asList(Array,Array2,Array3);
List<Future<String>> future = executor.invokeAll(taskList);
for(Future<String> result : future)
{
System.out.println(result.get());
}
}
最后的数字是 ID
变量是为了检查它是否打印出正确的...但是问题是,在控制台中,会发生这种情况...
current - [0, 3, 5, 0, 5, 4, 3, 2, 1, 4, 6, 1, 3, 6] - 1
current - [1, 3, 5, 0, 5, 4, 3, 2, 1, 4, 6, 1, 3, 6] - 3
current - [0, 3, 5, 0, 5, 4, 2, 2, 0, 4, 6, 1, 3, 6] - 1
current - [0, 3, 5, 0, 5, 4, 3, 2, 0, 4, 6, 1, 3, 6] - 2
第 1 行是正确的,ID 1 应该打印第一个索引在 0 到 1 范围内的数组。
但是 ID 3 和 2 不应该在第一个索引中有 0 或 1...这不会一直发生,但会出现在成千上万的控制台输出中
知道为什么会这样吗?因为这个我真的很紧张...T__T
编辑:添加 generateTpuMappingWithRange
private int[] generateTpuMappingWithRange(int[] iap, int startRange, int stopRange) {
final Logger log = Logger.getLogger(MarkovTest.class);
int maximumNoOfCoreIndex = 6;
int minimumNoOfCoreIndex = 0;
int firstIndex = 0;
int[] result = iap;
log.debug("OLD MAPPING = " + Arrays.toString(result));
// generate random
Random randomNum = new Random();
// generate number from 0 -> 13 (because last number will always be 6)
int randomIndex = randomNum.nextInt(iap.length - 1);
// last one will always be 6 so dont need to include that
int minusOrPlus = 0;
minusOrPlus = randomNum.nextBoolean() ? 1 : -1;
Task thisTask = this.model.getSwModel().getTasks().get(randomIndex);
PuType thisTaskPuType = domains.get(thisTask);
int[] newIndexValueRange = this.intervals.get(thisTaskPuType);
minimumNoOfCoreIndex = newIndexValueRange[0];
maximumNoOfCoreIndex = newIndexValueRange[1];
int newIndexValue = result[randomIndex] + minusOrPlus;
// Split 0-1, 2-3, 4-5 for 3 markov chain.
if (randomIndex == firstIndex) {
if (newIndexValue > stopRange) {
newIndexValue = startRange;
} else if (newIndexValue < startRange) {
newIndexValue = stopRange;
}
} else {
if (newIndexValue > maximumNoOfCoreIndex) {
newIndexValue = minimumNoOfCoreIndex;
} else if (newIndexValue < minimumNoOfCoreIndex) {
newIndexValue = maximumNoOfCoreIndex;
}
}
// if the new index value generated from line above surpass our maximum no of
// core, then it will return to number 0
// This may resolve to infinite loop if THE SAME randomIndex appear again and
// again and again and again, which hopefully wont be a thing for this
// implementation
result[randomIndex] = newIndexValue;
log.debug("NEW MAPPING = " + Arrays.toString(result));
log.debug(" location =" + randomIndex + " value =" + newIndexValue);
return result;
}
这里是代码的完整版本以防万一。
init()
方法基本上是生成2个HashMap,主要用来确定每个索引的maxmimum和minimum值。
public class MarkovTest implements Callable<String> {
static ExecutorService executor = Executors.newFixedThreadPool(3);
int startRange;
int stopRange;
long timeOutMiliseconds = 1000;
long maxIteration;
Amalthea model;
int[] ia;
int ID;
private final int nbCPUs;
private final int nbPUs;
private final HashMap<Task, PuType> domains = new HashMap<Task, PuType>();
private final HashMap<PuType, int[]> intervals = new HashMap<PuType, int[]>();
public MarkovTest(int[] ia, Amalthea model, int ID, int startRange, int stopRange) {
this.model = model;
this.ia = ia;
this.nbCPUs = CommonUtils.getNumberofCPUs(model);
// this.nbGPUs = CommonUtils.getNumberofGPUs(this.model);
this.nbPUs = CommonUtils.getNumberofPUs(model);
this.ID = ID;
this.startRange = startRange;
this.stopRange = stopRange;
init();
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
org.apache.log4j.BasicConfigurator.configure();
Logger.getRootLogger().setLevel(Level.INFO);
long startTime = System.currentTimeMillis();
int[] ia = { 5, 2, 5, 3, 3, 1, 3, 5, 1, 0, 0, 6, 4, 6 };
final Amalthea ama = AmaltheaLoader.loadFromFile(new File(SharedConsts.ECRTS_MODEL));
Callable<String> Array = new MarkovTest(ia, ama, 1, 0, 1);
Callable<String> Array2 = new MarkovTest(ia, ama, 2, 2, 3);
Callable<String> Array3 = new MarkovTest(ia, ama, 3, 4, 5);
List<Callable<String>> taskList = Arrays.asList(Array,Array2,Array3);
List<Future<String>> future = executor.invokeAll(taskList);
for(Future<String> result : future)
{
System.out.println(result.get());
}
long endTime = System.currentTimeMillis();
long elapsedTime = endTime - startTime;
System.out.println(" elapsed Time = " + elapsedTime);
System.out.println("Done");
}
@Override
public String call() {
String result = "yay";
long startTime = System.currentTimeMillis();
long endTime = startTime + timeOutMiliseconds * 1000;
while (System.currentTimeMillis() < endTime) {
int[] currentMapping = generateTpuMappingWithRange(ia, startRange, stopRange);
System.out.println(" current - " + Arrays.toString(currentMapping) + " - " + ID);
result = Arrays.toString(currentMapping);
}
return result;
}
private int[] generateTpuMappingWithRange(int[] iap, int startRange, int stopRange) {
final Logger log = Logger.getLogger(MarkovTest.class);
int maximumNoOfCoreIndex = 6;
int minimumNoOfCoreIndex = 0;
int firstIndex = 0;
int[] result = iap;
log.debug("OLD MAPPING = " + Arrays.toString(result));
// generate random
Random randomNum = new Random();
// generate number from 0 -> 13 (because last number will always be 6)
int randomIndex = randomNum.nextInt(iap.length - 1);
// last one will always be 6 so dont need to include that
int minusOrPlus = 0;
minusOrPlus = randomNum.nextBoolean() ? 1 : -1;
Task thisTask = this.model.getSwModel().getTasks().get(randomIndex);
PuType thisTaskPuType = domains.get(thisTask);
int[] newIndexValueRange = this.intervals.get(thisTaskPuType);
minimumNoOfCoreIndex = newIndexValueRange[0];
maximumNoOfCoreIndex = newIndexValueRange[1];
int newIndexValue = result[randomIndex] + minusOrPlus;
// Split 0-4, 5-10, 11-13 for 3 markov chain.
if (randomIndex == firstIndex) {
if (newIndexValue > stopRange) {
newIndexValue = startRange;
} else if (newIndexValue < startRange) {
newIndexValue = stopRange;
}
} else {
if (newIndexValue > maximumNoOfCoreIndex) {
newIndexValue = minimumNoOfCoreIndex;
} else if (newIndexValue < minimumNoOfCoreIndex) {
newIndexValue = maximumNoOfCoreIndex;
}
}
// if the new index value generated from line above surpass our maximum no of
// core, then it will return to number 0
// This may resolve to infinite loop if THE SAME randomIndex appear again and
// again and again and again, which hopefully wont be a thing for this
// implementation
result[randomIndex] = newIndexValue;
log.debug("NEW MAPPING = " + Arrays.toString(result));
log.debug(" location =" + randomIndex + " value =" + newIndexValue);
return result;
}
private void init() {
final Logger log = Logger.getLogger(CallableForMarkov.class);
for (final Task t : this.model.getSwModel().getTasks()) {
boolean cpu = false;
boolean gpu = false;
boolean defaultVal = false;
for (final CallGraphItem geb : t.getCallGraph().getItems()) {
if (geb instanceof Group) {
final Group cs = (Group) geb;
for (final CallGraphItem csi : cs.getItems()) {
if (csi instanceof RunnableCall) {
final RunnableCall trc = (RunnableCall) csi;
for (final CallGraphItem ri : trc.getRunnable().getRunnableItems()) {
if (ri instanceof Ticks) {
final Ticks ticks = (Ticks) ri;
if (null != ticks.getDefault() && ticks.getDefault().getAverage() > 0) {
defaultVal = true;
}
for (final Entry<ProcessingUnitDefinition, IDiscreteValueDeviation> e : ticks
.getExtended().entrySet()) {
if (!gpu && e.getKey().getPuType().equals(PuType.GPU)) {
gpu = true;
} else if (!cpu && e.getKey().getPuType().equals(PuType.CPU)) {
cpu = true;
}
}
}
}
// TODO check if there are runnables with different tick vals
}
}
}
}
if (cpu && !gpu) {
/* task can be mapped only to CPUs */
log.debug(t.getName() + " can be mapped to 0 --" + (this.nbCPUs - 1));
this.domains.put(t, PuType.CPU);
if (!this.intervals.containsKey(PuType.CPU)) {
this.intervals.put(PuType.CPU, new int[] { 0, this.nbCPUs - 1 });
}
} else if (gpu && !cpu) {
/* task can be mapped only to GPUs */
log.debug(t.getName() + " can be mapped to " + this.nbCPUs + "--" + (this.nbPUs - 1));
this.domains.put(t, PuType.GPU);
if (!this.intervals.containsKey(PuType.GPU)) {
this.intervals.put(PuType.GPU, new int[] { this.nbCPUs, this.nbPUs - 1 });
}
} else if (defaultVal || (gpu && cpu)) {
/* task can be mapped anywhere */
log.debug(t.getName() + " can be mapped to 0 --" + (this.nbPUs - 1));
this.domains.put(t, PuType._UNDEFINED_);
if (!this.intervals.containsKey(PuType._UNDEFINED_)) {
this.intervals.put(PuType._UNDEFINED_, new int[] { 0, this.nbPUs - 1 });
}
} else {
/* Task can be mapped nowhere */
log.fatal(t.getName() + " can be mapped nowhere");
}
}
}
}
看看我在你的代码摘录中的内嵌注释:
public static void main(String[] args) throws InterruptedException, ExecutionException {
org.apache.log4j.BasicConfigurator.configure();
Logger.getRootLogger().setLevel(Level.INFO);
long startTime = System.currentTimeMillis();
//-----> You have created an instance of ia
int[] ia = { 5, 2, 5, 3, 3, 1, 3, 5, 1, 0, 0, 6, 4, 6 };
final Amalthea ama = AmaltheaLoader.loadFromFile(new File(SharedConsts.ECRTS_MODEL));
//-----> You have passed the _same_ instance to all of the constructor calls
Callable<String> Array = new MarkovTest(ia, ama, 1, 0, 1);
Callable<String> Array2 = new MarkovTest(ia, ama, 2, 2, 3);
Callable<String> Array3 = new MarkovTest(ia, ama, 3, 4, 5);
...
//---->lets move a bit down to the method that's called within the Callable
private int[] generateTpuMappingWithRange(int[] iap, int startRange, int stopRange) {
...
int firstIndex = 0;
...
int randomIndex = random.nextInt(iap.length - 1);
...
//---> this part should make sure what you are stating, that "ID 1 should print array with first index in range 0 to 1." and this is correct
if (randomIndex == firstIndex) {
if (newIndexValue > stopRange) {
newIndexValue = startRange;
} else if (newIndexValue < startRange) {
newIndexValue = stopRange;
}
} else {
if (newIndexValue > maximumNoOfCoreIndex) {
newIndexValue = minimumNoOfCoreIndex;
} else if (newIndexValue < minimumNoOfCoreIndex) {
newIndexValue = maximumNoOfCoreIndex;
}
}
...
但是,正如我在上面的代码中提到的,您已将 same ia
实例传递给所有构造函数调用。
这意味着所有 3 个 MarkovTest
实例将在同一个 ia
上运行,单独修改它,因此您为数组的第一个元素设置的规则不起作用。
例如,当 MarkovTest
和 ID=2
得到 randomIndex == firstIndex
时,它会相应地修改 ia
的第一个索引,然后打印 ia
使用 更新并更正新的第一个值 。
之后,一个MarkovTest
和ID=1
运行,得到randomIndex != firstIndex
,所以它修改randomIndex
处ia
的值,然后打印ia
,之前更新但现在不正确的第一个值,以及未修改的值以及 randomIndex
处正确更新的新值。
对于每个 MarkovTest
,此循环重复直到 System.currentTimeMillis() < endTime
。
解法:
有几种解决方案,因为您将同一个实例传递给所有 3 个 MarkovTest
,您可以直接在 class 中初始化 ia
,而不需要那个构造函数参数。
如果你坚持要有构造函数参数,那么你可以:
int[] ia_copy;
public MarkovTest(int[] ia, Amalthea model, int ID, int startRange, int stopRange) {
this.model = model;
//----> create a copy like this:
ia_copy=new int[ia.length];
System.arraycopy( ia, 0, ia_copy, 0, ia.length );
this.nbCPUs = CommonUtils.getNumberofCPUs(model);
// this.nbGPUs = CommonUtils.getNumberofGPUs(this.model);
this.nbPUs = CommonUtils.getNumberofPUs(model);
this.ID = ID;
this.startRange = startRange;
this.stopRange = stopRange;
init();
}
只是不要忘记更改所有引用,尤其是在:
@Override
public String call() {
...
while (System.currentTimeMillis() < endTime) {
//----> ia to ia_copy
int[] currentMapping = generateTpuMappingWithRange(ia_copy , startRange, stopRange);
...
我不确定标题是不是detail/correct但是我不知道如何在标题中描述它所以我会尽力在这里描述它
我一直在尝试在 Java 中使用 callable 进行并发,但结果不正确,似乎线程已经相互重叠,而 运行...下面是
的调用函数@Override
public String call() {
String result = "yay";
long startTime = System.currentTimeMillis();
long endTime = startTime + timeOutMiliseconds * 1000;
while (System.currentTimeMillis() < endTime) {
int[] currentMapping = generateTpuMappingWithRange(ia, startRange, stopRange);
System.out.println(" current - " + Arrays.toString(currentMapping) + " - " + ID);
result = Arrays.toString(currentMapping);
}
return result;
}
generateTpuMappingWithRange()
函数只是生成另一个随机整数数组,第一个索引来自 startRange -> stopRange
(即 startRange = 0,stopRange = 2,然后 [0, 2, 1,] -> [1, 2, 1] 或 [2,2,1])
构造函数
public MarkovTest(int ID, int startRange, int stopRange) {
this.ID = ID;
this.startRange = startRange;
this.stopRange = stopRange;
init();
}
这是主要内容
public static void main(String[] args) throws InterruptedException, ExecutionException {
Callable<String> Array = new MarkovTest(1, 0, 1);
Callable<String> Array2 = new MarkovTest(2, 2, 3);
Callable<String> Array3 = new MarkovTest(3, 4, 5);
List<Callable<String>> taskList = Arrays.asList(Array,Array2,Array3);
List<Future<String>> future = executor.invokeAll(taskList);
for(Future<String> result : future)
{
System.out.println(result.get());
}
}
最后的数字是 ID
变量是为了检查它是否打印出正确的...但是问题是,在控制台中,会发生这种情况...
current - [0, 3, 5, 0, 5, 4, 3, 2, 1, 4, 6, 1, 3, 6] - 1
current - [1, 3, 5, 0, 5, 4, 3, 2, 1, 4, 6, 1, 3, 6] - 3
current - [0, 3, 5, 0, 5, 4, 2, 2, 0, 4, 6, 1, 3, 6] - 1
current - [0, 3, 5, 0, 5, 4, 3, 2, 0, 4, 6, 1, 3, 6] - 2
第 1 行是正确的,ID 1 应该打印第一个索引在 0 到 1 范围内的数组。 但是 ID 3 和 2 不应该在第一个索引中有 0 或 1...这不会一直发生,但会出现在成千上万的控制台输出中
知道为什么会这样吗?因为这个我真的很紧张...T__T
编辑:添加 generateTpuMappingWithRange
private int[] generateTpuMappingWithRange(int[] iap, int startRange, int stopRange) {
final Logger log = Logger.getLogger(MarkovTest.class);
int maximumNoOfCoreIndex = 6;
int minimumNoOfCoreIndex = 0;
int firstIndex = 0;
int[] result = iap;
log.debug("OLD MAPPING = " + Arrays.toString(result));
// generate random
Random randomNum = new Random();
// generate number from 0 -> 13 (because last number will always be 6)
int randomIndex = randomNum.nextInt(iap.length - 1);
// last one will always be 6 so dont need to include that
int minusOrPlus = 0;
minusOrPlus = randomNum.nextBoolean() ? 1 : -1;
Task thisTask = this.model.getSwModel().getTasks().get(randomIndex);
PuType thisTaskPuType = domains.get(thisTask);
int[] newIndexValueRange = this.intervals.get(thisTaskPuType);
minimumNoOfCoreIndex = newIndexValueRange[0];
maximumNoOfCoreIndex = newIndexValueRange[1];
int newIndexValue = result[randomIndex] + minusOrPlus;
// Split 0-1, 2-3, 4-5 for 3 markov chain.
if (randomIndex == firstIndex) {
if (newIndexValue > stopRange) {
newIndexValue = startRange;
} else if (newIndexValue < startRange) {
newIndexValue = stopRange;
}
} else {
if (newIndexValue > maximumNoOfCoreIndex) {
newIndexValue = minimumNoOfCoreIndex;
} else if (newIndexValue < minimumNoOfCoreIndex) {
newIndexValue = maximumNoOfCoreIndex;
}
}
// if the new index value generated from line above surpass our maximum no of
// core, then it will return to number 0
// This may resolve to infinite loop if THE SAME randomIndex appear again and
// again and again and again, which hopefully wont be a thing for this
// implementation
result[randomIndex] = newIndexValue;
log.debug("NEW MAPPING = " + Arrays.toString(result));
log.debug(" location =" + randomIndex + " value =" + newIndexValue);
return result;
}
这里是代码的完整版本以防万一。
init()
方法基本上是生成2个HashMap,主要用来确定每个索引的maxmimum和minimum值。
public class MarkovTest implements Callable<String> {
static ExecutorService executor = Executors.newFixedThreadPool(3);
int startRange;
int stopRange;
long timeOutMiliseconds = 1000;
long maxIteration;
Amalthea model;
int[] ia;
int ID;
private final int nbCPUs;
private final int nbPUs;
private final HashMap<Task, PuType> domains = new HashMap<Task, PuType>();
private final HashMap<PuType, int[]> intervals = new HashMap<PuType, int[]>();
public MarkovTest(int[] ia, Amalthea model, int ID, int startRange, int stopRange) {
this.model = model;
this.ia = ia;
this.nbCPUs = CommonUtils.getNumberofCPUs(model);
// this.nbGPUs = CommonUtils.getNumberofGPUs(this.model);
this.nbPUs = CommonUtils.getNumberofPUs(model);
this.ID = ID;
this.startRange = startRange;
this.stopRange = stopRange;
init();
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
org.apache.log4j.BasicConfigurator.configure();
Logger.getRootLogger().setLevel(Level.INFO);
long startTime = System.currentTimeMillis();
int[] ia = { 5, 2, 5, 3, 3, 1, 3, 5, 1, 0, 0, 6, 4, 6 };
final Amalthea ama = AmaltheaLoader.loadFromFile(new File(SharedConsts.ECRTS_MODEL));
Callable<String> Array = new MarkovTest(ia, ama, 1, 0, 1);
Callable<String> Array2 = new MarkovTest(ia, ama, 2, 2, 3);
Callable<String> Array3 = new MarkovTest(ia, ama, 3, 4, 5);
List<Callable<String>> taskList = Arrays.asList(Array,Array2,Array3);
List<Future<String>> future = executor.invokeAll(taskList);
for(Future<String> result : future)
{
System.out.println(result.get());
}
long endTime = System.currentTimeMillis();
long elapsedTime = endTime - startTime;
System.out.println(" elapsed Time = " + elapsedTime);
System.out.println("Done");
}
@Override
public String call() {
String result = "yay";
long startTime = System.currentTimeMillis();
long endTime = startTime + timeOutMiliseconds * 1000;
while (System.currentTimeMillis() < endTime) {
int[] currentMapping = generateTpuMappingWithRange(ia, startRange, stopRange);
System.out.println(" current - " + Arrays.toString(currentMapping) + " - " + ID);
result = Arrays.toString(currentMapping);
}
return result;
}
private int[] generateTpuMappingWithRange(int[] iap, int startRange, int stopRange) {
final Logger log = Logger.getLogger(MarkovTest.class);
int maximumNoOfCoreIndex = 6;
int minimumNoOfCoreIndex = 0;
int firstIndex = 0;
int[] result = iap;
log.debug("OLD MAPPING = " + Arrays.toString(result));
// generate random
Random randomNum = new Random();
// generate number from 0 -> 13 (because last number will always be 6)
int randomIndex = randomNum.nextInt(iap.length - 1);
// last one will always be 6 so dont need to include that
int minusOrPlus = 0;
minusOrPlus = randomNum.nextBoolean() ? 1 : -1;
Task thisTask = this.model.getSwModel().getTasks().get(randomIndex);
PuType thisTaskPuType = domains.get(thisTask);
int[] newIndexValueRange = this.intervals.get(thisTaskPuType);
minimumNoOfCoreIndex = newIndexValueRange[0];
maximumNoOfCoreIndex = newIndexValueRange[1];
int newIndexValue = result[randomIndex] + minusOrPlus;
// Split 0-4, 5-10, 11-13 for 3 markov chain.
if (randomIndex == firstIndex) {
if (newIndexValue > stopRange) {
newIndexValue = startRange;
} else if (newIndexValue < startRange) {
newIndexValue = stopRange;
}
} else {
if (newIndexValue > maximumNoOfCoreIndex) {
newIndexValue = minimumNoOfCoreIndex;
} else if (newIndexValue < minimumNoOfCoreIndex) {
newIndexValue = maximumNoOfCoreIndex;
}
}
// if the new index value generated from line above surpass our maximum no of
// core, then it will return to number 0
// This may resolve to infinite loop if THE SAME randomIndex appear again and
// again and again and again, which hopefully wont be a thing for this
// implementation
result[randomIndex] = newIndexValue;
log.debug("NEW MAPPING = " + Arrays.toString(result));
log.debug(" location =" + randomIndex + " value =" + newIndexValue);
return result;
}
private void init() {
final Logger log = Logger.getLogger(CallableForMarkov.class);
for (final Task t : this.model.getSwModel().getTasks()) {
boolean cpu = false;
boolean gpu = false;
boolean defaultVal = false;
for (final CallGraphItem geb : t.getCallGraph().getItems()) {
if (geb instanceof Group) {
final Group cs = (Group) geb;
for (final CallGraphItem csi : cs.getItems()) {
if (csi instanceof RunnableCall) {
final RunnableCall trc = (RunnableCall) csi;
for (final CallGraphItem ri : trc.getRunnable().getRunnableItems()) {
if (ri instanceof Ticks) {
final Ticks ticks = (Ticks) ri;
if (null != ticks.getDefault() && ticks.getDefault().getAverage() > 0) {
defaultVal = true;
}
for (final Entry<ProcessingUnitDefinition, IDiscreteValueDeviation> e : ticks
.getExtended().entrySet()) {
if (!gpu && e.getKey().getPuType().equals(PuType.GPU)) {
gpu = true;
} else if (!cpu && e.getKey().getPuType().equals(PuType.CPU)) {
cpu = true;
}
}
}
}
// TODO check if there are runnables with different tick vals
}
}
}
}
if (cpu && !gpu) {
/* task can be mapped only to CPUs */
log.debug(t.getName() + " can be mapped to 0 --" + (this.nbCPUs - 1));
this.domains.put(t, PuType.CPU);
if (!this.intervals.containsKey(PuType.CPU)) {
this.intervals.put(PuType.CPU, new int[] { 0, this.nbCPUs - 1 });
}
} else if (gpu && !cpu) {
/* task can be mapped only to GPUs */
log.debug(t.getName() + " can be mapped to " + this.nbCPUs + "--" + (this.nbPUs - 1));
this.domains.put(t, PuType.GPU);
if (!this.intervals.containsKey(PuType.GPU)) {
this.intervals.put(PuType.GPU, new int[] { this.nbCPUs, this.nbPUs - 1 });
}
} else if (defaultVal || (gpu && cpu)) {
/* task can be mapped anywhere */
log.debug(t.getName() + " can be mapped to 0 --" + (this.nbPUs - 1));
this.domains.put(t, PuType._UNDEFINED_);
if (!this.intervals.containsKey(PuType._UNDEFINED_)) {
this.intervals.put(PuType._UNDEFINED_, new int[] { 0, this.nbPUs - 1 });
}
} else {
/* Task can be mapped nowhere */
log.fatal(t.getName() + " can be mapped nowhere");
}
}
}
}
看看我在你的代码摘录中的内嵌注释:
public static void main(String[] args) throws InterruptedException, ExecutionException {
org.apache.log4j.BasicConfigurator.configure();
Logger.getRootLogger().setLevel(Level.INFO);
long startTime = System.currentTimeMillis();
//-----> You have created an instance of ia
int[] ia = { 5, 2, 5, 3, 3, 1, 3, 5, 1, 0, 0, 6, 4, 6 };
final Amalthea ama = AmaltheaLoader.loadFromFile(new File(SharedConsts.ECRTS_MODEL));
//-----> You have passed the _same_ instance to all of the constructor calls
Callable<String> Array = new MarkovTest(ia, ama, 1, 0, 1);
Callable<String> Array2 = new MarkovTest(ia, ama, 2, 2, 3);
Callable<String> Array3 = new MarkovTest(ia, ama, 3, 4, 5);
...
//---->lets move a bit down to the method that's called within the Callable
private int[] generateTpuMappingWithRange(int[] iap, int startRange, int stopRange) {
...
int firstIndex = 0;
...
int randomIndex = random.nextInt(iap.length - 1);
...
//---> this part should make sure what you are stating, that "ID 1 should print array with first index in range 0 to 1." and this is correct
if (randomIndex == firstIndex) {
if (newIndexValue > stopRange) {
newIndexValue = startRange;
} else if (newIndexValue < startRange) {
newIndexValue = stopRange;
}
} else {
if (newIndexValue > maximumNoOfCoreIndex) {
newIndexValue = minimumNoOfCoreIndex;
} else if (newIndexValue < minimumNoOfCoreIndex) {
newIndexValue = maximumNoOfCoreIndex;
}
}
...
但是,正如我在上面的代码中提到的,您已将 same ia
实例传递给所有构造函数调用。
这意味着所有 3 个 MarkovTest
实例将在同一个 ia
上运行,单独修改它,因此您为数组的第一个元素设置的规则不起作用。
例如,当 MarkovTest
和 ID=2
得到 randomIndex == firstIndex
时,它会相应地修改 ia
的第一个索引,然后打印 ia
使用 更新并更正新的第一个值 。
之后,一个MarkovTest
和ID=1
运行,得到randomIndex != firstIndex
,所以它修改randomIndex
处ia
的值,然后打印ia
,之前更新但现在不正确的第一个值,以及未修改的值以及 randomIndex
处正确更新的新值。
对于每个 MarkovTest
,此循环重复直到 System.currentTimeMillis() < endTime
。
解法:
有几种解决方案,因为您将同一个实例传递给所有 3 个 MarkovTest
,您可以直接在 class 中初始化 ia
,而不需要那个构造函数参数。
如果你坚持要有构造函数参数,那么你可以:
int[] ia_copy;
public MarkovTest(int[] ia, Amalthea model, int ID, int startRange, int stopRange) {
this.model = model;
//----> create a copy like this:
ia_copy=new int[ia.length];
System.arraycopy( ia, 0, ia_copy, 0, ia.length );
this.nbCPUs = CommonUtils.getNumberofCPUs(model);
// this.nbGPUs = CommonUtils.getNumberofGPUs(this.model);
this.nbPUs = CommonUtils.getNumberofPUs(model);
this.ID = ID;
this.startRange = startRange;
this.stopRange = stopRange;
init();
}
只是不要忘记更改所有引用,尤其是在:
@Override
public String call() {
...
while (System.currentTimeMillis() < endTime) {
//----> ia to ia_copy
int[] currentMapping = generateTpuMappingWithRange(ia_copy , startRange, stopRange);
...