LINUX.ORG.RU
ФорумTalks

Про состояние векторизации в последних версиях компилятора

 , , ,


0

4

Я обычно говняю ржавую мерзость за мерзотный синтаксис, но вот на этой конференции мне понравилось послушать про это вселенское зло:

Видео с конференции С++ Russia. Называется «производительность языка Rust» https://www.youtube.com/watch?v=g9mjctBfo5c

Заявляется, что проверки индексов не дают ржавому векторизовать циклы. Что вообще указывает на какой-то недостаток в архитектуре существующих компиляторов. Я погуглил что-нибудь на эту тему, нашел вот такую ссылку: https://www.nickwilcox.com/blog/autovec/ где автор пытался заставить компилятор работать по человечески на вот таком вот банальном коде

pub fn mix_mono_to_stereo(dst: &mut [f32], src: &[f32], gain_l: f32, gain_r: f32) {
    for i in 0..src.len() {
        dst[i * 2 + 0] = src[i] * gain_l;
        dst[i * 2 + 1] = src[i] * gain_r;
    }
}

Посмотрел на выхлоп компилятора, потом накидал похожий код на С++, посмотрел что выдает llvm, gcc… В общем, llvm генерит что-то совершенно демоническое. GCC делает компактный код, но к сожалению совсем не векторит, а впридачу ко всему еще и хрень какую-то творит, например грузит одно и тоже значение дважды из памяти. И проверки индексов тут явно ни при чем. Оно просто генерит дерьмо.

Что должен был сделать векторизатор здорового человека? Для начала предположить что цикл будет пердолиться долго, и подготовить операнды.

#вариант1:
    punpcklps xmm0,xmm1
    movlhps   xmm0,xmm0
#вариант2:
    pshufps   xmm0,xmm0,0
    pshufps   xmm1,xmm1,0

затем оценить сколько данных на входе:

    cmp edx,4
    jb  loop_x1
    sub edx,4
loop_x4:

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

#вариант1:
    movups    xmm2,[rsi]
    movaps    xmm3,xmm2
    pshufps   xmm2,xmm2,0b01010000
    pshufps   xmm3,xmm3,0b11111010
    pmulps    xmm2,xmm0 ;первые 2 пары
    pmulps    xmm3,xmm0 ;вторые 2 пары
    
#вариант2:
    movups    xmm2,[rsi]
    movaps    xmm4,xmm2
    pmulps    xmm2,xmm0
    pmulps    xmm4,xmm1
    movaps    xmm3,xmm2
    punpcklps xmm2,xmm4 ;первые 2 пары
    punpckhps xmm3,xmm4 ;вторые 2 пары

Кстати можете прямо щас посмотреть на выхлоп аналогичного «векторизованного» кода на С++ или расте и ужаснуться. Насколько же он, черт подери ужасен. Дальше надо данные записать. Можно сразу проверить каким-то образом что место в буфере есть, этот момент я упущу потому что мне решительно лень и вообще я уверено что разобраться сравнить число с 4 и сделать условный переход каждая собака умеет. А запись вообще-то можно сделать той же командой movdqu. Она на современных процах вполне рабочая. Дальше мы увеличиваем rsi на 16, уменьшаем edx на 4 и делаем jno loop_x4, иначе add edx,4 + jmp loop_x1.

Если бы современные компиляторы не были такими наркоманскими внутре, то реализовать подобный оптимизатор для них можно было бы например за ~20 ящиков хорошего пива. Цикл короткий, мы видим отношение выхода ко входу фиксированно 2 к 1 и повторяется монотонно и шаг итерации 8 байт, или половина регистра. Значит строительная единица - 2 умножения , один вход повторяется, другой чередуется и это повторяется два раза чтоб работать с 16 байтами. Это компилятор сделать смог бы. То есть мою логику абстрактаный компилятор повторить мог бы без каких-то запредельно сложных алгоритмов. Причем не только с массивом, но и например с матрицей и возможно даже со списком или строкой если там внутре не будет какого-то лютого ветвления и логики. Если добавить маскируемые векторные команды, которых в x86 нету в нормальном виде, дело пойдет еще проще.

В случае с проверкой индексов, можно как-то научить компилятор делать выводы, например что если индекс нарастает монотонно, то в векторизованном цикле надо сразу проверять его на N-кратное увеличение. Опять же, это не нерешаемая задача.

Вы ведь провели профилирование? Во сколько раз ваша версия здорового человека быстрее наркоманского выхлопа компилятора?

unDEFER ★★★★★
()

Вот ведь скотство-то какое.

dataman ★★★★★
()

предположить что цикл будет пердолиться долго
невыровненное чтение на самом деле не такое уж разрушительное

Как хорошо, что ты не пишешь компиляторы.

devl547 ★★★★★
()

Нет самого главного - замеров.

wandrien ★★★★
()

А разве с тех пор, как есть GPGPU, и с тех пор, как ему готовят код специальные либы и/или компиляторы, и с тех пор, как эти GPU пихают уже в тачки для рисования всяких VR на экране, а у любого Васяна ноут с видеокартой и этими самыми GPU, не пофиг ли на SIMD возможности CPU?

seiken ★★★★★
()
Ответ на: комментарий от seiken

у любого Васяна ноут с видеокартой и этими самыми GPU, не пофиг ли на SIMD возможности CPU?

AMD тоже так 15 лет назад подумали. А потом выгребали кое-как.

devl547 ★★★★★
()
Ответ на: комментарий от seiken

Особенно после того, как Китайцы в июне опять захватили первенство в HPC Top500 с 304-ядерным CPU, зная, что каждый гиперскейлер выпускает свой многоядерный процессор с 200-300 ядрами, и вспоминая, что Nvidia warp - это тот же самый SIMD вектор, хотя ей это нравится называть SIMT, то получается, что? Что получается? Пофиг или не совсем? Да и специальные либы для GPU сваливаются с неба, а не пишутся теми же самыми программистами, которые пишут многопоточные программы… Ведь так?

VIT ★★
()
Ответ на: комментарий от devl547

В защиту AMD следует вспомнить, что в 2008 году для неё стоял вопрос жизни или смерти. Или ты срочно распродаёшь активы, но сохраняешь ядро и восстаёшь из пепла, или тебя покупает Quallcomm. Именно тогда она продала своё кремневое производство и компиляторы с остальным софтом, оставив только ядро инженеров-проектировщиков серверных процессоров. А АTI уже была потом.

VIT ★★
()
Ответ на: комментарий от GAMer

При правильной аналогии, абсолютно то же самое. Надо сказать, что реально выполненное SVE я ещё пока нигде не видел. Вот чтобы выдал инструкцию «переключись с 512 на 2x256» и весь блок за 2 цикла переключается.

VIT ★★
()
Ответ на: комментарий от VIT

«переключись с 512 на 2x256» и весь блок за 2 цикла переключается

Я конечно о нём знаю только поверхностно, но вроде ж его физические реализации как раз не могут переключаться, и у нвидии фиксированно 256, а у фуджиков 512?

GAMer ★★★★★
()
Ответ на: комментарий от GAMer

Вот это и делает их одинаковыми. Считайте, что поток в warp это lane в векторе, и алгоритмы полностью переносимы до степени различий в реализации, конечно. В Интел была идея создать программно изменяемую ширину потоковой группы в PVC, но всё как всегда. Это был бы реально работающий аналог изменяемой длины вектора.

VIT ★★
()

Оно упирается в bandwidth памяти.

shdown ★★
()

Для начала предположить что цикл будет пердолиться долго

Откуда это предположить? У тебя джита нет, аннотаций нет, предположить неоткуда.

foror ★★★★★
()

Зачем, вообще, все эти гадания на кофейной гуще? Векторизовать нужно то, что указал разраб, если он не указал, то и не надо усложнять. Если ты пишешь хайлоад, системные библиотеки, у тебя должно быть понимание какой цикл нужно в avx, а какой не нужно. Указываешь компилятору и всё. А тот в худшем случае может выдать на консоль: «ну не шмогла я…» И там уже по ситуации, вплоть до замены компилятора. А если пишешь прикладуху, так твои проблемы, там и не нужно это всё.

foror ★★★★★
()
Последнее исправление: foror (всего исправлений: 1)
Ответ на: комментарий от VIT

Судя по всему все бюджеты ушли в рекламу «OpenCL и gpgpu в каждом пасьянсе с калькулятором».
На программистов денег уже не осталось.

А потом еще раз hsa рекламировали и терафлопс мощи в kaveri. Как он там, кстати?)

devl547 ★★★★★
()
Последнее исправление: devl547 (всего исправлений: 1)
Ответ на: комментарий от seiken

То-то дураки в эпл и арм всякие SME да AMX блоки придумывают вместо того чтобы все на GPU считать

cobold ★★★★★
()
Ответ на: комментарий от seiken

Видишь ли - SIMD бесплатен по факту (всё в рамках кеша и оперативки) а в GPU информацию надо скопировать и извлечь, при том по о-о-очень медленной шине ещё и с пигном большим. Потому если обработки на GPU много (взять какую-то текстурку, наложить эффекты на 100500 пикселей), то GPU это классно и замечательно. А если надо в цикле что-то сделать быстро, просто и в малых объёмах обработки или с обработкой которую в GPU архитектура самой GPU делать не даёт (половина вычислений векторизуется, а половина нет), то GPU нифига не выгоднее.

peregrine ★★★★★
()

ТС, ты в целом дело пишешь (про качество ассемблерного кода компиляторов, оно и правда низкое для 2026 года, потому как осталось на уровне архитектур этих самых компиляторов с 1987 и 2007 годов обросших подпорками и костылями), ресурсов на их развитие мало - это тебе не ИИ куда вливают миллиарды долларов все у кого они есть. Но без бенчмарков, с высказываниями вида:

предположить что цикл будет пердолиться долго

невыровненное чтение на самом деле не такое уж разрушительное

все твои речи являются прямой пропагандой качества хреновых компиляторов

peregrine ★★★★★
()
Ответ на: комментарий от seiken

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

seiken ★★★★★
()
Ответ на: комментарий от devl547

Все бюджеты на самом деле ушли на ATI. AMD перед покупкой стоила примерно $8B, а купила она ATI за $5.3B. AMD не могла себе позволить такую покупку, но рискнула. Было ли это выгодно ли нет, решайте сами, но даже через 10 лет, в 2016 году, AMD не смогла оправиться от потрясения.

VIT ★★
()

Кстати, почему в тегах нет Фортрана?

seiken ★★★★★
()
Ответ на: комментарий от VIT

в 2016 году

Потому что они просирали буквально все полимеры выпуском фикуса и APU без адекватной софтовой поддержки первого и второго. И повторюсь - маркетинговый отдел у них стабильно выдавал обещания, за которыми ничего не следовало.

Zen-то в 2017 вышел.

devl547 ★★★★★
()
Ответ на: комментарий от VIT

Было ли это выгодно ли нет, решайте сами

AMD сделало движение тазом в ту сторону, куда двигалась индустрия вычислений - на видеокарты^W "ускорители графических и иных рассчётов". Это движение обеспечило AMD заказами на playstation и google stadia, что в свою очередь обеспечило AMD их нынешними видеочипами.

В принципе, AMD сейчас уверенно стоит на двух ногах, а не на одной. При этом, надо помнить, что она конкурирует с гораздо более финансово крупными лидерами по каждому из направлений. Быть вторым на любом из этих двух рынков - это успешный успех. Так что AMD успешна дважды.

r--r--r--
()
Ответ на: комментарий от r--r--r--

Я согласен с тем, что сказано кроме выводов. Выбор был или любой ценой вскочить на уходящий GPU поезд, или производить сейчас графические процессоры для Nvidia и ATI вместо TSMC. Поскольку история не терпит сослагательного наклонения, говорить что лучше я не берусь, но имеем что имеем. AMD - вторая компания по производству графических процессоров, но без заводов и без коллектива программистов.

VIT ★★
()
Ответ на: комментарий от VIT

или производить сейчас графические процессоры для Nvidia и ATI вместо TSMC

Не думаю, что такая опция была.

без коллектива программистов

У них есть графический драйвер под windows с 3d ускорением, который регулярно оптимизируют под актуальные игры. На планете примерно две компании, у которых есть способность производить такой драйвер с полным циклом, включая регрессионное тестирование. Для такой задачи нужен коллектив разработчиков.

r--r--r--
()
Ответ на: комментарий от r--r--r--

Так что AMD успешна дважды.

ATI была изначально канадской фирмой. Для меня было забавно узнать, что даже некоторые студенты айтишники из Канады не знали, что ATI - отечественная для них контора…

seiken ★★★★★
()
Ответ на: комментарий от Shadow

Он стабильно хуже даже полностью опенсурсной mesa, включая падения там, где опенсурс работает:

2016
2020

Это при том, что amdgpu-pro разрабатывался под стадию.

r--r--r--
()
Ответ на: комментарий от seiken

Ну во-первых, какой-то SIMD иметь надо. Он нужен для работы с текстом, для какой-никакой 3д графики, потому что не все делается эффективно на GPU. Даже если полностью на indirect rendering перейти. memcpy надо ускорять.

Но SIMD нужен не такой как в X86 - во первых нужно маскирование по general purpose register. По битовой маске например. аналог palignr но с операндом регистром. аналогично shuffle-операции.

Вообще много чего нужно, например лучшая версия атомарных операций, когда spinlock ставится без обращения к памяти, просто на адрес без обращения к памяти. Нужно уметь ставить до 4х таких локов на процессор на аппаратном уровне. На usermode их реализовать через внеочередное выполнение, с лимитом инструкций в цепочке. Не как в risc-v всратый LR/SC который дрючит кэш и всё равно любая более-менее сложная задача превращается в танцы с бубном.

ckotctvo
() автор топика
Ответ на: комментарий от r--r--r--

У них есть графический драйвер под windows

Для такой задачи нужен коллектив разработчиков.

Драйвер, это только начало разговора. Без драйвера для своих устройств разговор даже не начинается. Для того, что бы AMD хотя бы начинать конкурировать с Nvidia, ей нужно сделать так, чтобы не только инженеры AMD писали код для AMD устройств. Это не вопрос пары дней, и не вопрос пары лет. Это серьёзное вложение в экосистему (разговор про switch в Си показал, что не все вообще понимают, что такое экосистема и начинают нести чушь про климат).

Вот пример экосистемы:

https://docs.nvidia.com

К сожалению, сегодня не существует вычислительной экосистемы вокруг AMD и Intel устройств в области вычислений на графических устройствах. Может быть и не будет.

VIT ★★
()
Ответ на: комментарий от VIT

Покупка ATI совершенно ни при чем. Более того, она спасла AMD. Это я знаю потому что питерское отделение амд курировали люди работавшие еще в ATI. Родом из России кстати. Вот они и рассказали какие там чудеса творились. Да и в отчетах которые каждый месяц приходили на почту это было видно. Их почему-то рассылали всем включая контракторов.

Следующие 10 лет AMD медленно списывала по кускам эту трату, но на самом деле больше за то что в 2008-2009м какие-то неизвестные структуры «прошли с шапкой» по крупным американским компаниям и собрали с них в общак какие-то баснословные суммы.

Например в hewlett-packard пришел некий лева аптекер с рекомендательным письмом от рептилоидов, поруководил, купил за конкий прайс «кирпич» и ушел. Компания претензий не имеет и благодарна что легко отделалась.

ckotctvo
() автор топика
Ответ на: комментарий от peregrine

да я код посмотрел. во-первых gcc вообще не векторизует. можно примерно оценить где упрется gcc и мой код на допустим K10: это обращения к памяти, у меня 1 чтение на 128бит и 4 записи по 64бита - потому что так сделано в железе - 1 запись 128бит идет в два порта.

На каждые 4 значения у меня будет 5 операций с памятью.

GCCшная версия производит 2 чтения и 2 записи, на каждый элемент. Зачем-то она два раза читает одно и то же число. На 4 значения - 16 операций с памятью.

void mix_mono_to_stereo(float * output, const float * src, unsigned src_len, float gain_l, float gain_r)
{
    for(unsigned i = 0; i < src_len; ++i) {
        output[2*i] = src[i] * gain_l;
        output[2*i+1] = src[i] * gain_r; 
    }
}

"mix_mono_to_stereo(float*, float const*, unsigned int, float, float)":
        movaps  xmm2, xmm0
        test    edx, edx
        je      .L1
        mov     edx, edx
        xor     eax, eax
        lea     rcx, [rsi+rdx*4]
.L3:
        movss   xmm0, DWORD PTR [rsi]
        mov     edx, eax
        add     rsi, 4
        mulss   xmm0, xmm2
        movss   DWORD PTR [rdi+rdx*4], xmm0
        movss   xmm0, DWORD PTR [rsi-4]
        lea     edx, [rax+1]
        add     eax, 2
        mulss   xmm0, xmm1
        movss   DWORD PTR [rdi+rdx*4], xmm0
        cmp     rcx, rsi
        jne     .L3
.L1:
        ret

У К10 2 порта для операций с памятью. По арифметике ни там ни тут затыка не будет. Итого на большом массиве ускорение ~16/5. То есть он даже не в память будет упираться а прямо в архитектуру процессорного ядра.

ckotctvo
() автор топика
Ответ на: комментарий от ckotctvo

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

VIT ★★
()
Ответ на: комментарий от VIT

К сожалению, сегодня не существует вычислительной экосистемы вокруг AMD и Intel устройств в области вычислений на графических устройствах.

Существует, может пожиже, чем у Nvidia и прямого аналога портала https://docs.nvidia.com нет, но экосистема имеется.

портал AMD Developer Documentation со ссылками на субпорталы - наиболее похоже, оттуда ссылки на сайты с документацией по GPU (GPU Open), по AI Instinct и др. Под AMD довольно немало уже портировано из мира обучений нейросетям того, что еще года три назад было только под Nvidia. Хотя и часто не всё или не полностью, к сожалению.

Про OpenCL и софт, с ним работающий, не надо забывать, хотя эта технология явно не в приоритете сейчас у AMD (в приоритете HIP - аналог CUDA), но и не заброшена и развивается.

anonymous_incognito ★★★★★
()
Ответ на: комментарий от VIT

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

ckotctvo
() автор топика
Ответ на: комментарий от ckotctvo

Я склонен доверять

Ну это нормально!

VIT ★★
()
Ответ на: комментарий от anonymous_incognito

Неужели вы думаете, что я ничего не знаю про HIP или OpenCL?

VIT ★★
()

Заявляется, что проверки индексов не дают ржавому векторизовать циклы.

for i in 0..src.len() {
        dst[i * 2 + 0] = src[i] * gain_l;
        dst[i * 2 + 1] = src[i] * gain_r;
    }

LOL.
За такое надо бить стальной линейкой по золотым ручкам растущим из жопы.
Во-первых, используйте итераторы, во вторых используйте чанки.

WatchCat ★★★★★
()
Ответ на: комментарий от ckotctvo

Забавно, clang 21.1 опцией -O3 на godbolt выдал такую простыню:

mix_mono_to_stereo(float*, float const*, unsigned int, float, float):
        test    edx, edx
        je      .LBB0_13
        mov     eax, edx
        add     edx, -12
        cmp     edx, 2147483636
        ja      .LBB0_4
        lea     rcx, [rsi + 4*rax]
        lea     rdx, [rdi + 8*rax]
        cmp     rsi, rdx
        setb    dl
        cmp     rdi, rcx
        setb    cl
        test    dl, cl
        je      .LBB0_10
.LBB0_4:
        xor     edx, edx
.LBB0_5:
        mov     rcx, rdx
        test    al, 1
        je      .LBB0_7
        movss   xmm2, dword ptr [rsi + 4*rdx]
        mulss   xmm2, xmm0
        lea     ecx, [rdx + rdx]
        movss   dword ptr [rdi + 4*rcx], xmm2
        movss   xmm2, dword ptr [rsi + 4*rdx]
        mulss   xmm2, xmm1
        movss   dword ptr [rdi + 4*rcx + 4], xmm2
        mov     rcx, rdx
        or      rcx, 1
.LBB0_7:
        lea     r8, [rax - 1]
        cmp     rdx, r8
        je      .LBB0_13
        sub     rax, rcx
        lea     rdx, [rsi + 4*rcx]
        add     rdx, 4
        add     ecx, ecx
        xor     esi, esi
.LBB0_9:
        movss   xmm2, dword ptr [rdx + 2*rsi - 4]
        mulss   xmm2, xmm0
        lea     r8d, [rcx + rsi]
        movss   dword ptr [rdi + 4*r8], xmm2
        movss   xmm2, dword ptr [rdx + 2*rsi - 4]
        mulss   xmm2, xmm1
        lea     r8d, [rcx + rsi + 1]
        movss   dword ptr [rdi + 4*r8], xmm2
        movss   xmm2, dword ptr [rdx + 2*rsi]
        mulss   xmm2, xmm0
        lea     r8d, [rcx + rsi + 2]
        movss   dword ptr [rdi + 4*r8], xmm2
        movss   xmm2, dword ptr [rdx + 2*rsi]
        mulss   xmm2, xmm1
        lea     r8d, [rcx + rsi]
        add     r8d, 3
        movss   dword ptr [rdi + 4*r8], xmm2
        add     rsi, 4
        add     rax, -2
        jne     .LBB0_9
        jmp     .LBB0_13
.LBB0_10:
        mov     edx, eax
        and     edx, -2
        movaps  xmm2, xmm0
        shufps  xmm2, xmm1, 0
        shufps  xmm2, xmm2, 216
        xor     ecx, ecx
.LBB0_11:
        movsd   xmm3, qword ptr [rsi + 4*rcx]
        unpcklps        xmm3, xmm3
        mulps   xmm3, xmm2
        movups  xmmword ptr [rdi + 8*rcx], xmm3
        add     rcx, 2
        cmp     rdx, rcx
        jne     .LBB0_11
        cmp     edx, eax
        jne     .LBB0_5
.LBB0_13:
        ret
WatchCat ★★★★★
()
Ответ на: комментарий от WatchCat

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

        movaps  xmm2, xmm0
        shufps  xmm2, xmm1, 0
        shufps  xmm2, xmm2, 216
.LBB0_11:
        movsd   xmm3, qword ptr [rsi + 4*rcx]
        unpcklps        xmm3, xmm3
        mulps   xmm3, xmm2
        movups  xmmword ptr [rdi + 8*rcx], xmm3
        add     rcx, 2
        cmp     rdx, rcx
        jne     .LBB0_11

вполне рабочий вариант, и я бы даже сказал что во, молодец шланг. Но всё что он высрал до этого-то зачем? прямо перед этим кодом буквально такой же но без векторизации(.LBB0_5:) а затем он же развернутый в четыре раза цикл для устрашения.

ckotctvo
() автор топика
Ответ на: комментарий от ckotctvo

Я код не читал, но предположу, что там скорее всего есть что-то из этого:

  • Проверка на алиасинг
  • Скалярный вариант, чтобы хвост обработать (если там не кратно размеру SIMD регистров)
  • Последнее (цикл тамошний), возможно, может оказаться в развёрнутом виде
  • Какая-нибудь машинерия по надёжному обеспечению корректной работы циклов
zezic ★★★★
()
Ответ на: комментарий от ckotctvo

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

gcc -S -O3 -masm=intel

Ну или что тебе больше нравится, если кресты, то смотри какие там опции и что за опции у компилятора растишки. Ещё опции на векторизации просмотри, явно может есть смысл указать что-то вроде

-march=native -ftree-vectorize для гарантий что всё правильно, ЕМНИП нужна опция -march=native, вторая должна входить в -O3. Можно ещё -fopt-info-vec-optimized посмотреть для наглядности. Но это всё фигня. Когда получишь бинари от компилятора и от ассемблера, то sudo perf stat /.a.out или как там у тебя бинарик будет называться и смотри по выхлопу сколько тактов у тебя. Тебя интересует cycles в первую очередь. Это твои такты процессора. Вот делаешь это для ручного кода на ассемблере и для компилятора. А дальше с этими цифрами идёшь на ЛОР и обсираешь компилятор ну или свои кривые руки, если компилятор окажется быстрее.

peregrine ★★★★★
()
Последнее исправление: peregrine (всего исправлений: 1)
Ответ на: комментарий от zezic

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

peregrine ★★★★★
()
Последнее исправление: peregrine (всего исправлений: 3)
Ответ на: комментарий от peregrine

… ты там какие-то строки кода считаешь. В идеале надо время засекать (не руками, либо с кода что точнее, либо через time что не так точно, но больше приближено к реальной работе) на большой задаче (чтоб учлась всякая шляпа вроде кешей, предсказаний и IO)

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

А вот по строкам ассемблера можно точнее сказать какой код будет исполняться быстрее или медленнее.

Enthusiast ★★★★
()
Ответ на: комментарий от peregrine

Спасибо, возможно это первое сообщение не просто постебаться, а по-существу. Я бы ещё добавил, что после своей ассемблерной вставки нужно не забыть проверить результат на корректность. А то ведь как бывает: «Смотрите, мужики, как быстро моя ассемблерная программа NaN считает!»

VIT ★★
()
Ответ на: комментарий от Enthusiast

В современных процессорах время отработки одного и того же исполняемого файла будет разниться от запуска к запуску.

Поэтому лучше измеряемый код снабдить своей rdtsc измерилкой и мерять не 5 циклов, а хотя бы 50000. Тогда повторяемость в пределах 20-30 циклов при разнице в алгоритме на 1000-2000 циклов будет хорошо видна.

VIT ★★
()
Закрыто добавление комментариев для недавно зарегистрированных пользователей (со score < 50)