【发布时间】:2016-10-09 14:53:20
【问题描述】:
我看了看,没有看到任何东西能完全回答我的问题。
我并不是最擅长创建准确的“现实生活”测试,所以我不确定这是否是问题所在。基本上我想创建一些简单的神经网络来创建Gridworld 的效果。这些神经网络的性能至关重要,我不希望隐藏层成为尽可能多的瓶颈。
我宁愿使用更多内存并更快,所以我选择使用数组而不是列表(因为列表对数组有额外的边界检查)。数组并不总是满的,但是因为 if 语句(检查元素是否为空)直到结束都是相同的,所以可以预测并且根本没有性能下降。
我的问题来自我如何存储数据以供网络处理。我认为由于 2D 数组将所有数据存储在一起,它会更好地缓存并且运行速度更快。但是从我的模拟测试来看,数组数组在这种情况下的表现要好得多。
一些代码:
private void RunArrayOfArrayTest(float[][] testArray, Data[] data)
{
for (int i = 0; i < testArray.Length; i++) {
for (int j = 0; j < testArray[i].Length; j++) {
var inputTotal = data[i].bias;
for (int k = 0; k < data[i].weights.Length; k++) {
inputTotal += testArray[i][k];
}
}
}
}
private void Run2DArrayTest(float[,] testArray, Data[] data, int maxI, int maxJ)
{
for (int i = 0; i < maxI; i++) {
for (int j = 0; j < maxJ; j++) {
var inputTotal = data[i].bias;
for (int k = 0; k < maxJ; k++) {
inputTotal += testArray[i, k];
}
}
}
}
这是定时的两个函数。每个“生物”都有自己的网络(第一个 for 循环),每个网络都有隐藏节点(第二个 for 循环),我需要找到每个输入的权重总和(第三个循环)。在我的测试中,我剥离了它,因此它并不是我在实际代码中所做的,但是发生了相同数量的循环(数据变量将有它自己的二维数组,但我不想可能扭曲结果) .从这里我试图了解哪个更快,令我惊讶的是数组的数组。
开始测试的代码:
// Array of Array test
Stopwatch timer = Stopwatch.StartNew();
RunArrayOfArrayTest(arrayOfArrays, dataArrays);
timer.Stop();
Console.WriteLine("Array of Arrays finished in: " + timer.ElapsedTicks);
// 2D Array test
timer = Stopwatch.StartNew();
Run2DArrayTest(array2D, dataArrays, NumberOfNetworks, NumberOfInputNeurons);
timer.Stop();
Console.WriteLine("2D Array finished in: " + timer.ElapsedTicks);
只是想展示我是如何测试它的。发布模式下的结果为我提供如下值:
Array of Arrays finished in: 8972
2D Array finished in: 16376
有人可以向我解释我做错了什么吗?为什么在这种情况下数组数组的速度要快这么多?二维数组不是都存储在一起的,这意味着它对缓存更友好吗?
请注意,我确实需要这个速度很快,因为它需要每帧汇总数十万 - 数百万个数字,就像我说的那样,我不希望这是一个问题。我知道这在未来很容易实现多线程,因为每个网络都是完全独立的,甚至每个节点也是完全独立的。
我想最后一个问题,这样的东西可以在 GPU 上运行吗?我认为 GPU 不会为拥有更多数量的输入/隐藏神经元的网络而奋斗。
【问题讨论】:
-
SO Post 中显示的类似内容
-
干杯谢谢。我查看了一些标题相似的帖子,但它们通常不会像那样表现。 John Leidegren 指出 2D 数组应该更快,但这并不是因为实施不善。你认为如果我创建自己的数据结构,将数据存储为一维数组但允许像二维数组一样访问,它会改变吗?
标签: c# arrays caching optimization