Пропускают ли современные процессоры умножение на ноль?

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


person user1214927    schedule 17.02.2012    source источник
comment
Как бы он пропустил умножение? Если в результате он дает 0, независимо от того, как быстро он это делает, он фактически выполнил умножение.   -  person Fred Foo    schedule 17.02.2012
comment
Меган Вакс упоминает этот вопрос в своем основном докладе RiscV. Она также упоминает один важный момент: это было бы ужасно с точки зрения безопасности, так как сделало бы многие алгоритмы уязвимыми для атак по времени. Это открывает побочный канал, в котором многие вычисления будут выполняться короче, чем другие, при пересечении такой нулевой точки.   -  person Błażej Michalik    schedule 10.02.2020


Ответы (2)


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

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

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

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

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

person Jerry Coffin    schedule 10.01.2014

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

person Puppy    schedule 17.02.2012