C# 紧循环性能C中的2D阵列与阵列阵列#
我看了一眼,看不出有什么东西能完全回答我的问题 我并不擅长创建准确的“现实生活”测试,所以我不确定这是否是问题所在。基本上,我想创建一些简单的神经网络来创建一些具有。这些神经网络的性能将是至关重要的,我不希望隐藏层尽可能成为瓶颈 我宁愿使用更多的内存和更快的速度,所以我选择使用数组而不是列表(因为列表对数组有额外的边界检查)。数组并不总是满的,但是因为if语句(检查元素是否为null)在结束之前是相同的,所以可以预测它,并且没有任何性能下降 我的问题来自如何存储数据以供网络处理。我认为,由于2D阵列将所有数据存储在一起,因此它在缓存方面会更好,运行速度也会更快。但是从我的模拟测试中可以看出,在这种情况下,阵列阵列的性能要好得多 一些代码:C# 紧循环性能C中的2D阵列与阵列阵列#,c#,arrays,caching,optimization,C#,Arrays,Caching,Optimization,我看了一眼,看不出有什么东西能完全回答我的问题 我并不擅长创建准确的“现实生活”测试,所以我不确定这是否是问题所在。基本上,我想创建一些简单的神经网络来创建一些具有。这些神经网络的性能将是至关重要的,我不希望隐藏层尽可能成为瓶颈 我宁愿使用更多的内存和更快的速度,所以我选择使用数组而不是列表(因为列表对数组有额外的边界检查)。数组并不总是满的,但是因为if语句(检查元素是否为null)在结束之前是相同的,所以可以预测它,并且没有任何性能下降 我的问题来自如何存储数据以供网络处理。我认为,由于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];
}
}
}
}
只是想展示一下我是如何测试它的。在释放模式下的结果给出如下值:
Array of Arrays finished in: 8972
2D Array finished in: 16376
有人能解释一下我做错了什么吗?为什么在这种情况下阵列的速度要快这么多?2D数组不是都存储在一起,这意味着它对缓存更友好吗
注意,我真的需要这个速度,因为它需要每帧数十万-数百万个数字的总和,就像我说的,我不希望这是一个问题。我知道这在将来很容易实现多线程,因为每个网络都是完全独立的,甚至每个节点都是完全独立的
最后一个问题,我想,像这样的东西可以在GPU上运行吗?我认为一个GPU不需要为拥有更多的网络和更多的输入/隐藏神经元而挣扎 在CLR中,有两种不同类型的数组:
- 向量,它是基于零的一维数组
- 数组,它可以具有非零基和多维
private void RunArrayOfArrayTest(float[][] testArray, Data[] data)
{
for (int i = 0; i < testArray.Length; i++) {
// These don't change in the loop below, so extract them
var row = testArray[i];
var inputTotal = data[i].bias;
var weightLength = data[i].weights.Length;
for (int j = 0; j < row.Length; j++) {
for (int k = 0; k < weightLength; k++) {
inputTotal += row[k];
}
}
}
}
private void RunArrayOfArrayTest(float[]testArray,Data[]Data)
{
对于(int i=0;i
如果您想获得缓存友好性并仍然使用向量,您可以使用单个
float[]
并自己执行索引。。。但我可能会从数组的方法开始。在这篇欢呼声中展示了类似的东西,谢谢。我看了一些标题类似的帖子,但它们通常不会像那样进入表演。John Leidegren指出2D数组应该更快,但这不是因为实现差。你认为如果我制作了自己的数据结构,将数据存储为一维数组,但允许像二维数组一样访问,它会改变这一点吗?谢谢你的回复。我认为我只是做错了什么,而不是锯齿阵列会更快。我可能会像你说的那样考虑使用1D数组(我以前也考虑过),但我不确定最干净的方法是什么。你认为这场演出值得努力吗?或者他们或多或少会是一样的?还有你所说的把这些变量从循环中去掉,这真的重要吗?我假设编译器足够聪明,可以自己做吗?@Lolop:我不想猜测编译器会做什么,或者使用单个数组会有什么好处。不过,我至少会尝试一下我在帖子中使用的方法——你已经有了度量它的代码,所以试试吧。如果速度不如您希望的那么快,那么您可以测试单阵列方法。。。请注意,可读性会有负面影响。我完全错了。只要照你说的做,跑步的时间几乎减少了一半。我认为我已经达到了循环可以达到的最快速度,仅仅运行空循环就需要大约2/3的总执行时间。谢谢你的帮助!我开始对它为什么不能按我预期的那样工作感到恼火。
private void RunArrayOfArrayTest(float[][] testArray, Data[] data)
{
for (int i = 0; i < testArray.Length; i++) {
// These don't change in the loop below, so extract them
var row = testArray[i];
var inputTotal = data[i].bias;
var weightLength = data[i].weights.Length;
for (int j = 0; j < row.Length; j++) {
for (int k = 0; k < weightLength; k++) {
inputTotal += row[k];
}
}
}
}