C++ указательная оптимизация

loganhackerdff

Известный
Автор темы
868
519
Раньше у меня был слабый ноутбук, и это оставило на мне душевную травму.
Теперь я все оптимизирую.
В функции я всё что весит больше 4 байт, я передаю по указателю (даже не по ссылке)
Я не использую range based циклы, потому-что они медленнее чем перебор с переменной.
Я правильно делаю?
Или так похож на старпёра
 
  • Ха-ха
Реакции: user390868
Решение
Вот что нагенерировал компилятор для range based:
range base.png

А вот что он нагенирировал для цикла с перебором:
incr.png


Как видишь код в обоих случаях одинаковый. Отличие есть только в том, что в цикле с переменной вместо размера вектора стоит переменная, в которую размер был прочитан из структуры вектора, но в кейсах с заранее не известной длиной у range based будет тоже чтение из структуры. Так что в скорости они не отличаются.

SR_team

like pancake
BH Team
4,809
6,487
я передаю по указателю (даже не по ссылке)
в скомпилированном коде это одно и то же
Я не использую range based циклы, потому-что они медленнее чем перебор с переменной.
не медленнее. Оба варианта компилятор оптимизирует из вида:
C++:
// перебор с переменной
for ( int i = 0; i < count; ++i ) {
    auto &el = arr[i];
    // ...
}
// range-based
for ( auto && el : arr ) {
    // ...
}
в:
C++:
for ( auto el = *arr; el < count * sizeof(el); el += sizeof(el) ) {
    // ...
}
 

loganhackerdff

Известный
Автор темы
868
519
в скомпилированном коде это одно и то же

не медленнее. Оба варианта компилятор оптимизирует из вида:
C++:
// перебор с переменной
for ( int i = 0; i < count; ++i ) {
    auto &el = arr[i];
    // ...
}
// range-based
for ( auto && el : arr ) {
    // ...
}
в:
C++:
for ( auto el = *arr; el < count * sizeof(el); el += sizeof(el) ) {
    // ...
}
Я так понял конструктор копирования по ссылке копирует всё из объекта , а указатель передаёт весь объект по ссылке?
Похоже нет, посмотри сам, второй вариант быстрее
C++:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include "vector"
//#include "string"
#include "chrono"
//#include "C:\LoganSnipps.h"
using namespace std;

struct A
{
    int a, b, c, d, h, n, q = {};
};

int main()
{
    while (true)
    {
        {
          
            std::vector<A> a(100);
            auto st = chrono::high_resolution_clock::now();
            for (auto&& val : a)
            {
                //sizeof(val) =  28
                std::cout << val.a << ' ';
            }
            chrono::duration<float> dura = chrono::high_resolution_clock::now() - st;
            cout << endl;
            cout << dura.count() << endl;
            cout << "It was &&" << endl;
        }
        cout << endl;
        {  
            std::vector<A> a(100);
            auto st = chrono::high_resolution_clock::now();
            for (size_t i = 0; i < a.size(); i++)
            {
                //sizeof(i) =  4
                //sizeof(a[i]) = 28
                std::cout << a[i].a << ' ';
            }
            chrono::duration<float> dura = chrono::high_resolution_clock::now() - st;
            cout << endl;
            cout << dura.count() << endl;
            cout << "It was size_t i = 0" << endl;
        }
        getchar();
    }

}
 

Вложения

  • ConsoleApplication5.exe
    16 KB · Просмотры: 5
Последнее редактирование:

SR_team

like pancake
BH Team
4,809
6,487
Я так понял конструктор копирования по ссылке копирует всё из объекта , а указатель передаёт весь объект по ссылке?
Похоже нет, посмотри сам, второй вариант быстрее
C++:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include "vector"
//#include "string"
#include "chrono"
//#include "C:\LoganSnipps.h"
using namespace std;

struct A
{
    int a, b, c, d, h, n, q = {};
};

int main()
{
    while (true)
    {
        {
         
            std::vector<A> a(100);
            auto st = chrono::high_resolution_clock::now();
            for (auto&& val : a)
            {
                //sizeof(val) =  28
                std::cout << val.a << ' ';
            }
            chrono::duration<float> dura = chrono::high_resolution_clock::now() - st;
            cout << endl;
            cout << dura.count() << endl;
            cout << "It was &&" << endl;
        }
        cout << endl;
        { 
            std::vector<A> a(100);
            auto st = chrono::high_resolution_clock::now();
            for (size_t i = 0; i < a.size(); i++)
            {
                //sizeof(i) =  4
                //sizeof(a[i]) = 28
                std::cout << a[i].a << ' ';
            }
            chrono::duration<float> dura = chrono::high_resolution_clock::now() - st;
            cout << endl;
            cout << dura.count() << endl;
            cout << "It was size_t i = 0" << endl;
        }
        getchar();
    }

}
Тебе поток вывода (std::cout) глаз замылил. Если поменять циклы местами, то результаты тоже поменяются в противоположную сторону

test.png
 
  • Нравится
Реакции: loganhackerdff

SR_team

like pancake
BH Team
4,809
6,487
Вот что нагенерировал компилятор для range based:
range base.png

А вот что он нагенирировал для цикла с перебором:
incr.png


Как видишь код в обоих случаях одинаковый. Отличие есть только в том, что в цикле с переменной вместо размера вектора стоит переменная, в которую размер был прочитан из структуры вектора, но в кейсах с заранее не известной длиной у range based будет тоже чтение из структуры. Так что в скорости они не отличаются.
 
  • Нравится
Реакции: Musaigen и loganhackerdff

kin4stat

mq-team · kin4@naebalovo.team
Всефорумный модератор
2,746
4,831
Вот что нагенерировал компилятор для range based:
Посмотреть вложение 71494
А вот что он нагенирировал для цикла с перебором:
Посмотреть вложение 71495

Как видишь код в обоих случаях одинаковый. Отличие есть только в том, что в цикле с переменной вместо размера вектора стоит переменная, в которую размер был прочитан из структуры вектора, но в кейсах с заранее не известной длиной у range based будет тоже чтение из структуры. Так что в скорости они не отличаются.
На godbolt.org можно смотреть в реалтайме asm код, который генерируют разные компиляторы с разными флагами компиляции
 

SR_team

like pancake
BH Team
4,809
6,487
На godbolt.org можно смотреть в реалтайме asm код, который генерируют разные компиляторы с разными флагами компиляции
Знаю, но asm менее нагляден, по этому я вставил скрин с псевдокодом из IDA