Re[33]: this_thread::sleep_for(1s);
От: lpd Черногория  
Дата: 10.01.17 10:55
Оценка: -2 :)
Здравствуйте, alex_public, Вы писали:

_>Здравствуйте, lpd, Вы писали:


_>>>Что касается кэша, то конечно же любая косвенность снижает его эффективность. Но какие-то самые банальные её уровни предсказатель всё же способен побороть. Но при многоуровневой косвенности эффективная работа кэша умирает сразу. )))

lpd>>В кэше не только данные, к которым обращение проходит последовательно, но и данные, к которым недавно было обращание. Причем второй вариант актуален гораздо чаще, чем первый. Кэшировать последовательное обращение нужно скорее для инструкций, чем для данных.

_>Вот если честно, мне уже надоело тут писать общеизвестные вещи по поводу оптимизации. Если не веришь мне на слово, то поищи информацию сам или же можем вместе поиграться в тесты на конкретных примерах. А писать что-то ещё на эту тему уже лень. )


Мне стало интересно, написал небольшой пример:
Идет обращение к гигабайту интов. В одном случае последовательно, в другом случае в случайном порядке.
#include <iostream>
#include <chrono>
#include <stdlib.h>
using namespace std;

#define SIZE 1000*1000*1000
int *map1, *map2;
void test(int *map) 
{
        int *array = new int[SIZE];
        int sum = 0;
        for (int i=0; i<SIZE; i++)
                sum += array[map[i]];
}
int main()
{
        map1 = new int[SIZE];
        for (int i=0;i<SIZE;i++)
                map1[i] = i;
        srand(time(0));
        map2 = new int[SIZE];
        for (int i=0;i<SIZE;i++)
                map2[i] = random()%SIZE;
        auto start1 = std::chrono::high_resolution_clock::now();
        test(map1);
        auto finish1 = std::chrono::high_resolution_clock::now();
        cout << std::chrono::duration_cast<std::chrono::nanoseconds>(finish1-start1).count() << "ns\n";

        auto start2 = std::chrono::high_resolution_clock::now();
        test(map2);
        auto finish2 = std::chrono::high_resolution_clock::now();
        cout << std::chrono::duration_cast<std::chrono::nanoseconds>(finish2-start2).count() << "ns\n";
}

Вывод:

2203765521ns
2621904089ns

Да, разница на 20%. Однако здесь только одна операция суммирования чисел, так что это можно считать верхней границей выигрыша, которую дает кэш. В реальных программах обработки больше, да и обращение к данным далеко не всегда последовательное, поэтому кэш не играет такой роли. Тем более, ошибочно говорить, что кэш миссы — решающий фактор, определящий отставание Java/C# в скорости от C++.
У сложных вещей обычно есть и хорошие, и плохие аспекты.
Берегите Родину, мать вашу. (ДДТ)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.