Как большие структуры могут быть переданы значением эффективно?

template
class ExceptionCatcher
{
public:
    template
    void doit(F&& f)
    {
        try 
        {
            ExceptionCatcher catcher;
            catcher.doit(std::forward(f));
        }
        catch(const E0 &)
        {
            std::cout << __PRETTY_FUNCTION__ << '\n';
        }
    }
};

template
class ExceptionCatcher
{
public:
    template
    void doit(F&& f)
    {
        try 
        {
            f();
        }
        catch(const E0 &)
        {
            std::cout << __PRETTY_FUNCTION__ << '\n';
        }
    }
};

https://wandbox.org/permlink/dAUQtb9RWvMZT4b6

9
задан Erik Engheim 13 May 2009 в 14:47
поделиться

6 ответов

Хорошо, поэтому я попытался последовать совету и профилировать свой код, используя указатели и значения. Еще посмотрел ассемблерный код. Похоже, что характеристики производительности на x86 сильно отличаются от PPC. На PPC двоичный интерфейс к C указывал, что аргументы будут помещены в регистры (их было так много на выбор), однако кажется, что даже на 64-битной системе x86 требуется, чтобы аргументы помещались в стек.

Это объясняет, почему на x86 передача по указателю всегда кажется быстрее. Однако я заметил, что компилятор очень хочет встроить. Так что не имело значения, как я это сделал. Итак, я предполагаю, что вывод состоит в том, чтобы использовать любую удобную для вас передачу.

Я думаю, что предпочтения передаются по значению, потому что работа с копиями значений в некоторой степени безопаснее. Мой тестовый пример представлял собой структуру, состоящую из 4 двойников (так что я думаю, что на большинстве платформ это 32 байта).

4
ответ дан 4 December 2019 в 21:51
поделиться

Если вы поищете в Интернете, вы найдете несколько рекомендаций по размеру байта для передачи по ссылке и значению. Я бы почти никому из этого не поверил. Единственный способ узнать , что конкретная структура является проблемой, - это

Профилировать ее

Это единственный способ на 100% узнать, что существует проблема.

Прежде, чем скептики прыгают. in. Да, есть несколько очевидных случаев. Я бы, например, никогда не передавал структуру по значению, если бы в ней было, скажем, 100 членов. Но это было бы не из-за проблем с производительностью, а больше из-за проблем с пространством стека.

3
ответ дан 4 December 2019 в 21:51
поделиться

В C ++ есть правило передавать все не из следующего списка как ссылку const , потому что производительность по существу никогда не будет хуже. Список исключений:

  • элементарные типы ( int и т. Д.),
  • указатели,
  • пустые типы (типы тегов),
  • функционально-подобные типы (функторы) и
  • итераторы.

Я не уверен, можно ли это применить непосредственно к C (кроме очевидных типов, которых нет в C), но, возможно, применимы аналогичные рекомендации.

2
ответ дан 4 December 2019 в 21:51
поделиться

Не пренебрегайте той ролью, которую выравнивание играет в вашем тестировании. Если вы передаете числа с плавающей запятой или удваивается, а ваши структуры не выровнены по соответствующим границам, процессор может получить часть вашего значения, сдвинуть ее, а затем сложить остальное перед сохранением. Я думаю, что большинство современных компиляторов будут использовать DTRT (выравнивая структуру, когда она объявлена), но если вы оптимизируете пространство, то это, вероятно, будет проблемой.

Хммм, теперь, когда я думаю об этом, отнеситесь к этому серьезно. скверны, так как я не занимался низкоуровневым кодированием на архитектуре x86 со времен Pentium Pro ...

0
ответ дан 4 December 2019 в 21:51
поделиться

Обычно примитивные типы я передаю по значению, все остальное по ссылке. Это мое практическое правило.

-1
ответ дан 4 December 2019 в 21:51
поделиться

Некоторые компиляторы могут определить оптимальный размер за вас. Если я правильно помню, компилятор TI28xx автоматически преобразует передачу по значению в передачу по ссылке, если структура превышает определенный размер.

1
ответ дан 4 December 2019 в 21:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: