Подтвердить что ты не робот

Применяет ли приведение типов дополнительные циклы процессора

Имеет ли приведение типов в C/С++ дополнительные циклы процессора?

Я понимаю, что в некоторых случаях следует потреблять дополнительные циклы процессора. Подобно typecasting от float до integer, где ЦП должен требовать преобразования структуры float в integer.

float a=2.0;
int b= (float)a;

Я хотел бы понять случаи, когда он будет/не будет потреблять дополнительные циклы процессора.

4b9b3361

Ответ 1

Я хотел бы сказать, что "преобразование между типами" - это то, над чем мы должны смотреть, а не есть ли какой-либо бросок или нет. Например

 int a = 10;
 float b = a; 

будет таким же, как:

 int a = 10;
 float b = (float)a;

Это также относится к изменению размера типа, например.

 char c = 'a';
 int b = c; 

это будет "растягивать c в размер int из одного байта [с использованием байта в смысле C, а не в 8-битном смысле]", что потенциально добавит дополнительную инструкцию (или дополнительный такт к используемой инструкции) выше и выше самой базы данных.

Обратите внимание, что иногда эти преобразования вовсе не очевидны. На x86-64 типичный пример использует int вместо unsigned int для индексов в массивах. Поскольку указатели 64-разрядные, индекс необходимо преобразовать в 64-разрядный. В случае без знака это тривиально - просто используйте 64-битную версию регистра, значение уже введено, поскольку операция 32-разрядной загрузки будет нулевой заполнять верхнюю часть регистра. Но если у вас есть int, это может быть отрицательным. Таким образом, компилятор должен будет использовать инструкцию "sign extend this to 64 bits". Обычно это не проблема, когда индекс вычисляется на основе фиксированного цикла, и все значения являются положительными, но если вы вызываете функцию, когда неясно, является ли параметр положительным или отрицательным, компилятору, безусловно, придется увеличить значение, Аналогично, если функция возвращает значение, которое используется как индекс.

Однако любой разумно компетентный компилятор не будет бездумно добавлять инструкции для преобразования чего-либо из своего собственного типа в себя (возможно, если оптимизация отключена, это может произойти, но минимальная оптимизация должна увидеть, что "мы переходим от типа X к тип X, это ничего не значит, давайте отнимем его" ).

Итак, вкратце, приведенный выше пример не добавляет никакого дополнительного штрафа, но, безусловно, есть случаи, когда "преобразование данных из одного типа в другой добавляет дополнительные инструкции и/или циклы синхронизации к коду".

Ответ 2

Он будет потреблять циклы, где он изменяет базовое представление. Таким образом, он будет потреблять циклы, если вы конвертируете число с float в int или наоборот. В зависимости от архитектуры приведение типа int к char или long long к int может потреблять или не использовать циклы (но чаще всего они будут). Приведение между типами указателей будет потреблять циклы, только если задействовано множественное наследование.

Ответ 3

Существуют разные типы приведений. С++ имеет разные типы операторов трансляции для разных типов трансляций. Если мы посмотрим на это в этих терминах,...

static_cast обычно будет стоить, если вы переходите от одного типа к другому, особенно если целевой тип отличается от типа источника. static_cast иногда используются для приведения указателя от производного типа к базовому типу. Это может также иметь стоимость, особенно если производный класс имеет несколько оснований.

reinterpret_cast обычно не будет иметь прямую стоимость. Говоря кратко, этот тип приведения не изменяет значение, он просто изменяет его интерпретацию. Обратите внимание, однако, что это может иметь косвенную стоимость. Если вы переинтерпретируете указатель на массив байтов как указатель на int, тогда вы можете оплачивать затраты каждый раз, когда вы разыскиваете этот указатель, если указатель не выровнен по мере того, как ожидает платформа.

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

dynamic_cast, который используется для перевода с указателя на базовый класс на указатель на производный класс, безусловно, имеет стоимость, поскольку он должен - как минимум - проверить, подходит ли преобразование.

Когда вы используете традиционный C, вы, по сути, просто просите компилятор выбрать более конкретный тип трансляции. Итак, чтобы выяснить, есть ли у вашего C cast стоимость, вам нужно выяснить, какой тип отливки действительно есть.

Ответ 4

DL и наслаждайтесь руководствами Agner Fog:
http://www.agner.org/optimize/
1. Оптимизация программного обеспечения на С++: руководство по оптимизации для платформ Windows, Linux и Mac
Это огромный PDF, но для начала вы можете проверить:

14.7 Не смешивайте поплавок и двойные
14.8. Переходы между числами с плавающей запятой и целыми числами