Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 紧循环性能C中的2D阵列与阵列阵列#_C#_Arrays_Caching_Optimization - Fatal编程技术网

C# 紧循环性能C中的2D阵列与阵列阵列#

C# 紧循环性能C中的2D阵列与阵列阵列#,c#,arrays,caching,optimization,C#,Arrays,Caching,Optimization,我看了一眼,看不出有什么东西能完全回答我的问题 我并不擅长创建准确的“现实生活”测试,所以我不确定这是否是问题所在。基本上,我想创建一些简单的神经网络来创建一些具有。这些神经网络的性能将是至关重要的,我不希望隐藏层尽可能成为瓶颈 我宁愿使用更多的内存和更快的速度,所以我选择使用数组而不是列表(因为列表对数组有额外的边界检查)。数组并不总是满的,但是因为if语句(检查元素是否为null)在结束之前是相同的,所以可以预测它,并且没有任何性能下降 我的问题来自如何存储数据以供网络处理。我认为,由于2D

我看了一眼,看不出有什么东西能完全回答我的问题

我并不擅长创建准确的“现实生活”测试,所以我不确定这是否是问题所在。基本上,我想创建一些简单的神经网络来创建一些具有。这些神经网络的性能将是至关重要的,我不希望隐藏层尽可能成为瓶颈

我宁愿使用更多的内存和更快的速度,所以我选择使用数组而不是列表(因为列表对数组有额外的边界检查)。数组并不总是满的,但是因为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中,有两种不同类型的数组:

  • 向量,它是基于零的一维数组
  • 数组,它可以具有非零基和多维
您的“数组数组”是CLR术语中的“向量向量向量”

基本上,向量比数组快得多。阵列可能会在以后的CLR版本中进一步优化,但我怀疑它是否会得到与向量相同的爱,因为它们相对很少使用。要使CLR阵列更快,您可以做的不多。正如您所说,它们将更加缓存友好,但它们会受到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];
            }
        }
    }
}