2012-02-17 2 views
6

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

+1

Как бы он «пропустил» умножение? Если в результате он дает 0, независимо от того, насколько быстро он это делает, он фактически произвел умножение. –

ответ

-2

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

8
  1. Современные процессоры - что вы подразумеваете под этим? Вы имеете в виду наиболее часто используемые (например, x86, AMD64, ARM) или совсем недавно разработанные. Каждая архитектура процессора имеет свои собственные свойства. Более того, каждая компания (например, Intel или AMD) может делать процессор по-другому (обычно это секрет компании).

  2. Как вы сомневаетесь, я сомневаюсь в этом. Вы знаете, даже проверяя, равен ли число равным нулю два раза, прежде чем КАЖДОЕ умножение будет слишком накладным, если вы учтете, насколько оптимизирован низкий процент операций умножения.

  3. Оптимизация, как это сделало бы CPU более дорогостоящим.

Предположим, что есть 1% умножений на ноль (и, вероятно, намного ниже) в средней программе. Это означало бы, что сравнение с нолем должно было бы в 200 раз быстрее, чем умножение на просто учетная запись для накладных расходов (и многое другое, чтобы это было полезно на практике).

Я думаю, что вы слишком много смотрите на этот вопрос с точки зрения человека. Когда вы умножаетесь, вы ясно видите, что одна из множителей равна нулю и заканчивается. Но, однако, с компьютерами все очень отличается. Фактически компьютер должен проверить все 64 или 32 бита, чтобы убедиться, что что-то равно нулю.

  1. Я бы не стал беспокоиться, был ли я вами. Производители процессоров и составители компиляторов делают все возможное, чтобы максимизировать производительность. У них есть литературная мысль обо всем.
+1

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

+0

Несомненно. :) Я думаю, что мой ответ охватывает это. Особенно последний абзац. –

+0

Вы забыли, насколько быстрее это может быть сделано в аппаратном обеспечении. – Puppy

1

Это сильно варьируется в зависимости от процессора и (в некоторых случаях) типа (ов) операндов.

Старые/простые процессоры обычно используют алгоритм умножения что-то вроде этого:

integer operator*(integer const &other) { 
    unsigned temp1 = other.value; 
    unsigned temp2 = value; 
    unsigned answer = 0; 

    while (temp1 != 0) { 
     if (temp1 & 1) 
      answer += temp2; 
     temp2 <<= 1; 
     temp1 >>=1; 
    } 
    return integer(answer); 
} 

Поскольку цикл выполняется только тогда, когда/если temp1 != 0, цикл, очевидно, не будет выполняться, если temp1 начинается как 0 (но, как написанная здесь, не будет пытаться оптимизировать для другого операнда 0).

Это, однако, принципиально один бит в алгоритме времени. Например, при умножении 32-разрядных операндов, если каждый бит имеет шанс установить 50:50, мы ожидаем в среднем приблизительно 16 итераций.

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

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

Смежные вопросы