我有一个方法接受一个数组(浮点数或双精度数),开始和结束索引,然后对startIndex到endIndex范围内的索引进行一些元素操作.
基本上它看起来像这样:
public void Update(float[] arr, int startIndex, int endIndex)
{
if (condition1)
{
//Do some array manipulation
}
else if (condition2)
{
//Do some array manipulation
}
else if (condition3)
{
if (subcondition1)
{
//Do some array manipulation
}
}
}
Run Code Online (Sandbox Code Playgroud)
方法比这长,并涉及将一些元素设置为0或1,或者规范化数组.问题是我需要在那里传递两个float[]和double[]数组,并且不希望有一个重复的代码接受double[].
性能也很关键,因此我不想创建一个新double[]数组,向其投射浮点数组,执行计算,然后通过强制转换为浮点数来更新原始数组.
是否有任何解决方案可以避免重复的代码,但也尽可能快?
下面的代码返回不同的值NExpectation和Expectation.如果我尝试相同的,NormalDistribution[]我会得到收敛错误NExpectation(但最终的结果仍然0适用于所有这些).是什么导致了这个问题?
U[x_] := If[x >= 0, Sqrt[x], -Sqrt[-x]]
N[Expectation[U[x], x \[Distributed] NormalDistribution[1, 1]]]
NExpectation[U[x], x \[Distributed] NormalDistribution[1, 1]]
Run Code Online (Sandbox Code Playgroud)
输出:
-0.104154
0.796449
Run Code Online (Sandbox Code Playgroud) 我有一个代码,它根据另一个小数组中的值更新数组.
for (var i = 0; i < result.Length; i++)
{
var c = cards[i];
result[i] -= one[c.C0] + one[c.C1];
}
Run Code Online (Sandbox Code Playgroud)
其中c是一个结构是一对从一甲板表示卡的字节.
one是一个52的数组大小(从甲板上的52张牌中的每一张都有条目)
我写了一个基准来分析这段代码:
private void TestCards2(int testRepetitions, float[] result, float[] one, Cards[] cards)
{
for (var r = 0; r < testRepetitions; r++)
for (var i = 0; i < result.Length; i++)
{
var c = cards[i];
result[i] -= one[c.C0] + one[c.C1];
}
}
Run Code Online (Sandbox Code Playgroud)
设置testRepetitions= 2500万,并使用256个元素(result.Length = 256)的数组,它在我的机器上运行大约8.5秒.
这是Cards结构:
struct …Run Code Online (Sandbox Code Playgroud) 我正在进行蒙特卡罗模拟.工作在许多不同的机器之间进行分区(通常大约150个).
每次迭代后,每个工作人员将其结果发送到服务器.从所有工作人员获得结果后,服务器会计算更新并将其发送回所有工作人员.
该循环重复100-1000次迭代.
在所有工作人员发送结果之前,服务器无法计算更新,因此如果99名工作人员需要1秒完成迭代而第100名工作人员需要10秒,那么整个迭代需要10秒.
问题是GC会在某些迭代中随机启动一些工作人员,因此会导致这些工作人员花费更多时间,从而减慢整个过程.
例如,在#1迭代期间,#58工作者需要10秒,其他工作人员需要8秒.在迭代#2中,不同的工作者需要更长的时间,依此类推.
这增加的开销似乎约为20-30%.
我想做的是指示GC在迭代发生时不要进行任何收集.仅收集每次10次迭代(以便所有工作人员同步其集合),或在发送结果后收集,以及从服务器获取更新之前收集.
这是我正在尝试做的伪代码:
public void Algorithm()
{
for (var iteration = 0; iteration < 1000; iteration++)
{
PerformIteration(); //don't do any GC inside.
SendResults();
//Now there is a small time window to perform GC
//before results from the server arrive (thats usually sub 0.5sec window)
WaitForUpdate();
}
}
Run Code Online (Sandbox Code Playgroud)
设置:GCSettings.LatencyMode = GCLatencyMode.SustainedLowLatency帮助了很多,但仍然有很大的开销.
每个工人有244克的压头,远远超过模拟要求.此外,几乎所有内容都被缓存,因此无需进行Gen2集合.