Re[5]: Откуда эта лютая любовь к знаковым целым?
От: Alexander G Украина  
Дата: 08.05.20 05:49
Оценка:
Здравствуйте, netch80, Вы писали:


AG>>(MSVC похоже никуда не идёт, он тупо делает реальное сравнение в обоих случаях a + 1 > a)


N>Ну, похоже, MSVC сильно отстал. Хотя это какого года версия? Они с 2015 кричат про переход на SSA, там многое должно заметно поменяться.


2019.
На godbolt почти свежак:

https://godbolt.org/z/j-oupf

Превью (последний, 1 мая 2020) не лучше

N>>>Что сравнивали-то? Intel рисует (почти) противоположное — для длинного умножения времена одинаковы, а для короткого (которому пофиг на знак) на 1-2 такта меньше (3 вместо до 5).

AG>>Обычное деление достаточно больших чисел int64_t / uint64_t, компиляция MSVC x64, беззнаковые ощутимо быстрее. Нужно воспроизвести?

N>Это уже речь про деление, а перед этим было про умножение


N>Вообще, если настроение, киньте код, я сверю в своих условиях.


#include <atomic>
#include <chrono>
#include <cstdint>
#include <iostream>

template<typename Integer>
Integer MultiplyDivide(Integer number, Integer numerator, Integer denominator)
{
    return number * numerator / denominator;
    // на самом деле _mul128 _div128, ну или _umul128 _udiv128 для беззанковых,
    // но для портабельности между компиляторами пусть так
}

template<typename Integer>
struct Benchmark
{
    // чтобы не выоптимизировались; компиляторы пока ещё не научились оптимизировать атомики
    std::atomic<Integer> number{ 123'456'789 };
    std::atomic<Integer> numerator{ 1'000'000'000 };
    std::atomic<Integer> denominator{ 10'000 };
    std::atomic<Integer> result{ 0 };

    std::chrono::duration<double, std::milli> Run()
    {
        auto start = std::chrono::steady_clock::now();
        for (unsigned i = 0; i != 100'000'000; i++)
        {
            result.store(
                MultiplyDivide<Integer>(
                    number.load(std::memory_order_relaxed),
                    number.load(std::memory_order_relaxed),
                    number.load(std::memory_order_relaxed)),
                std::memory_order_relaxed);
        }
        return std::chrono::steady_clock::now() - start;
    }
};

int main()
{
    for (unsigned i = 0; i != 2; i++)
    {
        std::cout << Benchmark<std::uint64_t>{}.Run().count() << "ms unsinged\n";
        std::cout << Benchmark<std::int64_t>{}.Run().count() << "ms singed\n";
    }
}


1558.57ms unsinged
1633.12ms singed
1548.84ms unsinged
1644.11ms singed
Русский военный корабль идёт ко дну!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.