Современные процессоры пропускают умножения на ноль? - PullRequest
6 голосов
/ 17 февраля 2012

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

Ответы [ 3 ]

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

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

  3. Такая оптимизация сделает процессор более дорогим.

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

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

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

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

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

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 итераций.

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

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

0 голосов
/ 17 февраля 2012

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

...