K & R задает вопрос к ответу на исходный вопрос - PullRequest
2 голосов
/ 04 ноября 2010

Я продолжал пытаться обернуть голову вокруг решения проблемы K & R 7-8, пока не нашел это решение (с исходной проблемой) прямо на этом сайте.Я не могу комментировать ответ (вероятно, из-за его возраста);единственный способ, которым я мог бы внести свой вклад в этот вопрос, - это опубликовать на него ответ, который я счел неуместным.Поэтому я решил создать этот тесно связанный вопрос, основанный на выбранном «ответе», который казался мне логичным, пока я не дошел до этой точки (касающейся реализации функции в качестве макроса):

«Повторяйте это как макрос очень часто, и« экономия места »быстро становится затратой, поскольку битовая маскировка имеет фиксированный размер.»

Единственная проблема заключается в том, что функциязвонки также занимают время.«Переход» к месту расположения функции, откладывание хранилища для локальной переменной (ей), а затем фактическое вычисление сравнения - все это занимает время.

Так как именно реализуется макрос, который проверяет значение ASCII длясимвол медленнее, чем первая функция, которая включает в себя поиск в таблице (с учетом этого)?

Как возможно, что вызов функции может занять меньше времени, чем сравнение двух целых чисел, одно из которых уже находится в памяти, иодин из которых является константой?Мне кажется, что повторные вызовы функции и макроса со временем все равно приведут к тому, что макрос будет быстрее.

Мой образ мышления неправильный?Я думаю, что так и должно быть, поскольку это не было затронуто в первоначальном вопросе.

Я был бы рад, если бы кто-то пролил некоторый свет на это.

1 Ответ

3 голосов
/ 04 ноября 2010

Прежде всего, обратите внимание, что стоимость, которую они упоминают, составляет размер , а не скорость. Например, предположим, что макрос расширяется до 16 байт кода. Предположим далее, что функция компилируется в 32 байта кода, а вызов функции занимает 6 байтов кода (конечно, ни один из них не гарантирован, но все они, вероятно, по крайней мере в общем стандарте для 32-битного кода) код).

В этом случае, если вы используете функцию, но вызываете ее только из одного места, вы получите 38 байтов кода. Если вместо этого вы используете макрос, вы получите только 16 байтов кода для экономии 22 байтов. Если вы используете макрос в двух местах, вы получите 32 байта кода против 44 байтов, если бы вы использовали функцию - все еще экономию, но меньшую. Немного забегая вперед, давайте предположим, что вы использовали его из 10 разных мест в своем коде. В этом случае макрос будет занимать 160 байт, а функция - только 92 байта.

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

Даже в лучшем случае вы можете запланировать задержку не менее 50 нс для извлечения некоторых данных из памяти (а 75-100 нс довольно распространены). Так же, как в среднем, давайте предположим, что 75 нс. Типичный современный процессор выполняет около 1,8 команд за такт, а на (скажем) 2,5 ГГц время тактового цикла составляет 0,4 нс. Это означает, что за 75 нс он может (в среднем) выполнить что-то вроде 75 / 0,4 * 1,8 = 337,5 инструкции. Вызов, выполнение и возврат из функции, о которой мы говорим здесь, где-то порядка полдюжины инструкций - так что в тесном цикле, к тому времени, когда вы получите код для макроса из памяти, как только вы может выполнить функцию из кэша где-то около 56 раз.

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

...