Добавление целых чисел из 2 массивов с использованием Vector <int>занимает больше времени, чем в обычном цикле for - PullRequest
0 голосов
/ 09 апреля 2020

Я пытаюсь использовать Vector для добавления целочисленных значений из 2 массивов быстрее, чем традиционное для l oop.

Количество моих векторов равно: 4, что должно означать, что функция addArrays_Vector должна работать В 4 раза быстрее чем: addArrays_Normally

var vectSize = Vector<int>.Count;

Это верно для моего компьютера:

Vector.IsHardwareAccelerated

Как ни странно, это критерии:
addArrays_Normally takes 475 milliseconds addArrays_Vectortakes 627 milliseconds

Как это возможно? Разве addArrays_Vector не должно занимать всего около 120 миллисекунд? Интересно, правильно ли я это делаю?

        void runVectorBenchmark()
        {
            var v1 = new int[92564080];
            var v2 = new int[92564080];
            for (int i = 0; i < v1.Length; i++)
            {
                v1[i] = 2;
                v2[i] = 2;
            }
            
            //new Thread(() => addArrays_Normally(v1, v2)).Start();
            new Thread(() => addArrays_Vector(v1, v2, Vector<int>.Count)).Start();
        }
        void addArrays_Normally(int[] v1, int[] v2)
        {
            Stopwatch stopWatch = new Stopwatch();
            stopWatch.Start();
            int sum = 0;
            int i = 0;
            for (i = 0; i < v1.Length; i++)
            {
                sum = v1[i] + v2[i];
            }
            stopWatch.Stop();
            MessageBox.Show("stopWatch: " + stopWatch.ElapsedMilliseconds.ToString() + " milliseconds\n\n" );
        }
        void addArrays_Vector(int[] v1, int[] v2, int vectSize)
        {
            Stopwatch stopWatch = new Stopwatch();
            stopWatch.Start();
            int[] retVal = new int[v1.Length];
            int i = 0;
            for (i = 0; i < v1.Length - vectSize; i += vectSize)
            {
                var va = new Vector<int>(v1, i);
                var vb = new Vector<int>(v2, i);
                var vc = va + vb;
                vc.CopyTo(retVal, i);
            }
            stopWatch.Stop();
            MessageBox.Show("stopWatch: " + stopWatch.ElapsedMilliseconds.ToString() + " milliseconds\n\n" );
        }

1 Ответ

1 голос
/ 09 апреля 2020

Две функции разные. И похоже, что память ОЗУ является узким местом:

  • в первом примере

        var v1 = new int[92564080];
        var v2 = new int[92564080];
    
        ...
    
        int sum = 0;
        int i = 0;
        for (i = 0; i < v1.Length; i++)
        {
            sum = v1[i] + v2[i];
        }
    

Код читает оба массива один раз. Таким образом, потребление памяти составляет: sizeof(int) * 92564080 * 2 == 4 * 92564080 * 2 == 706 МБ .

  • во втором примере

        var v1 = new int[92564080];
        var v2 = new int[92564080];
    
        ...            
    
        int[] retVal = new int[v1.Length];
        int i = 0;
        for (i = 0; i < v1.Length - vectSize; i += vectSize)
        {
            var va = new Vector<int>(v1, i);
            var vb = new Vector<int>(v2, i);
            var vc = va + vb;
            vc.CopyTo(retVal, i);
        }
    

Код читает 2 входных массива и записывает их в выходной массив. Потребление памяти составляет не менее sizeof(int) * 92564080 * 3 == 1 059 МБ

Обновление:

ОЗУ намного медленнее, чем кэш-память ЦП / ЦП , Из этой замечательной статьи о пропускной способности памяти Математика Салфетки примерно:

L1 Пропускная способность: 210 ГБ / с

...

Пропускная способность ОЗУ : 45 ГБ / с

Таким образом, дополнительное потребление памяти может пренебречь ускорением векторизации.

И упомянутое видео на Youtube сравнивает другой код, невекторизованный код из видео выглядит следующим образом, который потребляет столько же памяти, сколько векторизованный код:

    int[] AddArrays_Simple(int[] v1, int[] v2)
    {
        int[] retVal = new int[v1.Length];
        for (int i = 0; i < v1.Length; i++)
        {
            retVal[i] = v1[i] + v2[i];
        }
        return retVal;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...