Pull to refresh

Comments 29

А почему

#include <windows.h>

?

И всякие WORD вместо стандартных тиров данных. Много видел бенчмарков и всегда люди, при их написании стараются использовать максимально стандартные типы данных и конструкции, чтобы можно было сравнивать разные платформы/компиляторы.
1) Проглядел typdef > думал виндовый WORD
2) Проглядел виндовый Performance counter, думал используете утилиту time.

Вопрос снимается :)
Сейчас пишется новый супер тест, в котором будет увеличена «разрядность», то есть будет:
typedef unsigned __int64 _WORD;
typedef struct
{
	_WORD low;
	_WORD high;
} _DWORD;

Таким образом, для 64-х битных компиляторов настанет лафа в виде возможности intrinsic функции _mul128.

Еще очень странно, что __int128 в Visual Studio зарезервирован, но не используется, keyword not supported on this architecture, а то бы можно использовать его. Ничего, скоро и до gcc доберусь, там он есть.
Скачал, попробовал — в новом компиляторе со скоростью стало еще хуже.
64 bit — 18.3008 sec, 32 bit — 19.7172 sec (это на AMD)
Никаких мифов не развенчано, тк тест совершенно бредовый. Что измеряется не понятно. Скорость 5ти инструкций? К тому же О2 нево всех компиляторах включает loop unrolling, а здесь он сильно может изменить ситуацию.
Если хочется потестить целочисленную арифметику, не надо изобретать велосипед, когда есть GMP.
Спасибо, обязательно воспользуюсь. А еще меня очень интересует поведение OpenSSL — какая получится скорость с различными компиляторами.
> пусть даже и с поддержкой multi-threading

Немножко ошибаетесь. Core i5-2500, как и всё семейство i5 (за исключением двухядерного Core i5-2390T процессоров в первом поколении) не имеет поддержки HT. 8 потоков предоставляют только процессоры i7.
> процессоров в первом поколении
Рррррр. «Я всегда буду нажимать предпросмотр». «Я всегда буду нажимать предпросмотр». «Я всегда буду нажимать предпросмотр».
А зачем время замеряется вместе с memcmp(RES, C, sizeof(RES)?
Там это вынесено за внутренний цикл, поэтому почти не влияет.
А сколько раз вы проводили тест для каждого случая? В каких пределах колебались результаты?
Делал на Windows 7 — колебания были достаточно большие, плюс минус несколько секунд. В фоне ничего специально не крутилось.

Еще делал на Windows 8 (последний пререлиз) — как ни странно, там вообще результаты без колебаний с точностью до 0,1 сек. То ли Win8 настолько стабильная, то ли просто свежеустановленная — пока непонятно. И еще на Windows 8 было немного быстрее, так что все результаты оттуда.

Может быть, нужно в таблице отобразить еще и версию Windows (отдельно 7, отдельно 8)?
Да эти результаты интересны. Может конечно в таблицу не добавлять, но отразить это наблюдение в статье.
Еще запускал в Windows XP (guest) под эмулятором VirtualBox (Win7 была host) — скорость один в один как и без эмулятора, то есть скорость на guest получилась такая же как и скорость на host. Отсюда вывод, что в VirtualBox эмуляция полностью хардверная.
Я попробовал этот код под VS 2010. Результаты неутешительны: программа не реагирует на слово volatile, и все равно оптимизирует внутренний цикл в main — там в коде нет ни одного умножения. Чтобы ее хоть как-то обмануть, пришлось написать

        for( j=0; j<1000000; ++j)
        {
             for(int u=0;u<QUANTITY;u++) A[u]+=j;
             Mul(C, A, B);
             res1+=C[7];
        }


и все встало на места:
на AMD FX-8120:
32 бит — 82.2 сек
64 бит — 21.9 сек

на i5, 2.67 GHz
32 бит — 88.6 сек
64 бит — 16.3 сек

Причина большого времени в 32 битном коде — компилятор не понимает, как умножить (_DWORD) *(A++) * h и вызывает функцию _allmul
Честно написанный на ассемблере 32-битный код показал: на AMD — 24.7 сек, на i5 — 29.9 сек. (но это ни о чем не говорит: под конкретные процессоры код никак не оптимизирован).
Поделитесь пожалуйста, своим ассемблерным кодом, хочется провести сравнение человек vs оптимизирующий компилятор.
Пожалуйста. yadisk.cc/d/dxbZ2m_mhuX

описание для C++:
extern «C» Mul128(unsigned int *res,unsigned int *A,unsigned int *B);

Только когда будете сравнивать — поделитесь, пожалуйста, кодом, который сгенерил компилятор. А то мало ли, что…
Что-то у Вас не так с 32-х битным кодом, почему он такой не быстрый? Точно включен -O2?
Еще попробуйте с ключом /Fa<имя файла> получить ассемблерный листинг.
Он должен быть похож на этот /http://pastebin.com/JrHmdXtx
Хотя бы первая строчка такая? Microsoft ® Optimizing Compiler Version 16.00.40219.01
А вы посмотрите на свой код — на функцию main. К моменту, когда она добралась до строчки 567, все умножение (кстати, тоже через _allmul) уже закончилось. И только в этот момент начинается цикл 1000000 раз. Что в нем происходит, я пока не понял, но это явно какое-то сложение — ни единой команды умножения в нем нет. У себя я видел то же самое — поэтому и пришлось испортить код модификацией массива A. Причем если я менял только A[0], программа это понимала и оставляла только 4 умножения, остальные выкидывала. Пришлось менять все 4 элемента.
А ведь и правда, что-то у меня компилятор повыбрасывал все умножения, только сложение оставил.
Вот так нужно сделать, вызывать функцию по указателю, тогда точно не сможет выбросить:
    void (*mul)( _WORD *C, _WORD *A, _WORD *B ) = Mul;
    mul(C, A, B); //вместо Mul
Тоже вариант. И mul сделать глобальной переменной. Но надо будет все равно проверить результат.
Можете выложить ассемблерный код для 32 бит, сгенерированный Intel? Очень уж интересно, как они в несколько раз выигрывают в производительности.
Еще раз перепроверил, похоже что там ф-ия Mul не вызывалась, а вставлялась прямо в код main, что плохо отражалось на скорости (она была выше реальной за счет оптимизации). Поэтому сегодня опять исправил исходник, сейчас указатель на Mul записывается в файл и читается из файла, теперь-то точно компилятор не сможет догадаться, как это оптимизировать.

Обновил табличку, сейчас Intel дает менее 23 сек — выкладываю ассемблерный листинг:
IA-32, Version 12.0.0.104 Build 20101006
IA-32, Version 12.1.5.344 Build 20120612
Там все одинаково с точностью до названий регистров, но время немного разное, новый лучше.

Ваш ассемблерный код дает чуть более 25 сек — выкладываю и его тоже
(там добавлен один adc, иначе были проблемы с результатом)
Интересно какие бы результаты дали GCC и Watcom (ставлю на Watcom :)
Sign up to leave a comment.

Articles