LINUX.ORG.RU

Нужно ли учить ассемблер?


2

3

Пишу на С++. Нужно ли учить ассемблер? МатЧасть (устройство оперативной памяти, указатели, сколько какая переменная занимает памяти) и так далее примерно знаю (опыт кодинга на с++).

Также очень поверхностно знаю как работает процессор(читал разные статьи на хабре).

Будет ли мне профить от учения ассемблера (Под профитом понимаю лучшее понимание Си-шного кода при роботе с памятью указателями и разные принципы оптимизации)

UPD Мне все равно на мой заработок. Я хочу программировать как бог.

Перемещено mono из talks



Последнее исправление: knotri (всего исправлений: 1)

Ответ на: комментарий от anonymous

Сливает в говно.

Какой дистрибутив? В SLES'е одиннадцатом SSE-оптимизацию выкинули (из-за флешплейера, что ли?). Хотя, AVX'а, там может быть, ещё и нет.

nt - в l1d? куллстори.

У тебя две копии в кэше, вот и куллстори.

Тут на него покласть.

Потому что код ничего полезного не делает, кроме как 8кб копирует?

Что ты знаешь о реальных программах? Ты можешь 10раз повторить «биржа», «фпга» - «всё говно», только что это меняет?

Я знаю, понятное дело, не всё, но многое.

Копирование рамы на тех же avx без анрола не сливает на 10-20% как раньше не потому, что «штеуд стал умнее», а лишь из-за того, что avx - это уже почти кешлайн.

Кэшлайн здесь не при чём. При чём - количество load и store портов, а также их ширина.

Когда же ты копируешь в кеше(да и вообще что-то делаешь в кешах), то по определению без анролла штеуд не может.

Увы, пара десятков мегабайт кэша в моём случае - это песчинка в пустыне памяти. Памяти так много, что если ничего не делать, то процессор 25-30% времени тратит на обновление TLB.

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

Сопляк, то есть. Пешком под стол ходил, когда C++ в СССР появился.

ага.

Переводчиков и граммар-наци 80lvl.

это никак не говорит про их lvl в C++.

emulek
()

Тред не читал.

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

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

Ну дак выкати пруфцы? Не на рекламных беклетиках, а реальные, которые бы противоречили моим словам. Не можешь, как и mv не может, да и никогда не сможешь, ибо это невозможно в текущих реальиях.

Ты 10раз можешь кукарекать о том, что кто-там не разбирается в теме, что кто-то идиот, но есть конкретный факт - штеуд не может без анрола. Это легко доказал я пруфцыми выше. А твоё балабольство - лишь балабольство.

anonymous
()
Ответ на: комментарий от BRE

Здесь ты сморозил про один 16 битный регистр на процессоре 8086

детка, шла-бы ты в школу, тренировать навыки чтения.

emulek
()
Ответ на: комментарий от anonymous

Ну дак выкати пруфцы?

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

anonymous
()
Ответ на: комментарий от emulek

Тебе нравится называть 40-летних мужиков «детка»? А ты веселенький. :)

Ну а по теме, тебе пора начать читать ту хрень, которую ты пишешь.

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

Какой дистрибутив? В SLES'е одиннадцатом SSE-оптимизацию выкинули (из-за флешплейера, что ли?). Хотя, AVX'а, там может быть, ещё и нет.

Без разницы какая - сольёт в говно. Она в glibc.

У тебя две копии в кэше, вот и куллстори.

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

Потому что код ничего полезного не делает, кроме как 8кб копирует?

Это полезно, я тебе уже рассказал про то, что что угодно он делай - без анрола будет сливать в говно. Это твои жалкие оправдания. Что делает полезного мемкопи? Ничего, о как - выкинуть и забыть.

Я знаю, понятное дело, не всё, но многое.

Конкретного ты ничего не знаешь - в этом и суть.

Кэшлайн здесь не при чём. При чём - количество load и store портов, а также их ширина.

А где я говорил, что там кешлайн причем - я сказал, что мувы шириной почти в кешлайн. Это так низко.

Подробней, как вы объясните сей эффект: мемкопи на sse медленней мемкопи на avx, без анролла конечно. nt vs nt, t vs t. Чутка(3-5%), но быстрее.

Увы, пара десятков мегабайт кэша в моём случае - это песчинка в пустыне памяти. Памяти так много, что если ничего не делать, то процессор 25-30% времени тратит на обновление TLB.

http://pastebin.com/F0bud1Ew - так, к слову.

А причем тут ваш случай и зачем вы его приплетаете сюда? Есть объективный факт - штеуд без анрола не может, то что в вашем случае на это покласть - не даёт вам право с этим спорить и что-то доказывать.

Конечно игнор половины поста мне не по нраву, но всё же. Даже на примитивные вещи упирающиеся в памят(т.е. 0 полезной нагрузки) анролл даёт профит. Чем больше полезной(т.е. кол-во инструкий акромя mov над тем, что мы читаем/пишем) нагрузки выполяет процессор - тем профитней анролл(пропорциональный рост), а если нагрузка не упирается в память - анрол даёт разы.

3%->~400+% - это профит от арола, который растёт с ростом полезной нагрузки на константу времени - ВСЕГДА. Это аксиома в мире штеуда.

Если в ваших задачах полезной нагрузки в районе нуля, то это проблемы ваших задач, но никак не является аргумент и категорчно заявлять на лоре об этом нен адо, повторю уже 10-20й раз.

anonymous
()
Ответ на: комментарий от BRE

Тебе нравится называть 40-летних мужиков «детка»?

нет. Не нравится. Дожить до 40 лет, и не научится читать — это плохо. Сочувствую.

Ну а по теме, тебе пора начать читать ту хрень, которую ты пишешь.

я её ещё и помню.

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

Иди на свой недофорум - я с тобой поговорю.

anonymous
()
Ответ на: комментарий от emulek

Так попробуй формулировать свои мысли так, что бы тебя понимали.

Про 8086 не надо, ляпнул так ляпнул, в будущем... Читая тебя, создается впечатление, что чем меньше ты в теме разбираешся, тем больше ты в ней пишешь. Думаю со мной многие согласятся.

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

лучше напиши загрузочный сектор, переведи систему в виртуальный режим адресации, драйвер для floppy и напиши драйвер для клавиатуры и обработчик прерываний от таймера, потом создать процесс в userspace, потом добавь файловую систему и эмулятор терминала, потом добавить планировщик задач, потоки ввода вывода и можно попробовать написать свою библиотеку c, потом можно будет портировать gnu программы на свою систему, тогда более или менее появится представление о работе компьютера, но «писать как бог» это не научит, лучше уж наверно почитать Седжвика, полезнее будет, если цель именно такая: «писать как бог»

и потом для всего этого не нужен ассемблер, нужен си

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

Про 8086 не надо, ляпнул так ляпнул

да задолбали вы уже к словам придираться. Сам подумай, с помощью какой магии XCHG REG,REG в x86 выполняется столько же, сколько MOV REG,REG? Вот как нагуглишь ответ — возвращайся.

Читая тебя, создается впечатление, что чем меньше ты в теме разбираешся, тем больше ты в ней пишешь. Думаю со мной многие согласятся.

ВНЕЗАПНО: я тоже так думаю. Смысл мне с вами общаться на темы, в которых вы нихрена не понимаете(по сравнению со мной)?

emulek
()
Ответ на: комментарий от IvanR

Нужно ли учить ассемблер?

лучше напиши <tl;dr> для всего этого не нужен ассемблер

и в этом весь ЛОР.

emulek
()
Ответ на: комментарий от anonymous

Без разницы какая - сольёт в говно. Она в glibc.

Если glibc использует то же расширение, то слив будет минимальным, чисто за счёт оверхеда.

Ты знаешь, как твой код будет работать на первом AVX? Я знаю: он будет работать медленней SSE2.

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

8кб + 8кб - это половина L1D, или весь целиком, если HT включен. Эвиктится будет так, что свист стоять будет.

Это полезно, я тебе уже рассказал про то, что что угодно он делай - без анрола будет сливать в говно.

Определи «в говно»? И «что угодно» тоже?

А где я говорил, что там кешлайн причем - я сказал, что мувы шириной почти в кешлайн. Это так низко.

Ты бредишь.

http://pastebin.com/F0bud1Ew - так, к слову.

И? Ты про TLB-то понял? Троганье сколько-нибудь большого количества страничек выдавит код из STLB. В твоём случае, когда кода всего сотня байт, ничего страшного, но в нормальном продукте пенальти такое будет, что memcpy вдруг начнёт работать быстрее.

3%->~400+% - это профит от арола, который растёт с ростом полезной нагрузки на константу времени - ВСЕГДА. Это аксиома в мире штеуда.

Ну вот есть два лоад порта и один стор (до хасвелла, но мы ж про ВСЕГДА?). Если двигать данные, то писать получается в два раза медленней, чем читать.

Есть один порт для XMM-арифметики. Если считать контрольную сумму на SSE, то упрётся всё в этот порт, а не в скорость фетча инструкций.

rep movs работает медленней развёрнутой портянки только на netburst.

Комментируй своё ВСЕГДА.

mv ★★★★★
()

Да.

Но не прямо таки учить, а чтобы ты понимал ассемблерный код. Очень помогает. Я, например, как посмотрю, что мне sdcc делает из кода, аж рыдать хочется! А вот ARM'овский gcc очень даже огого!

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от knotri

можешь, конечно. ассемблер - язык процессора, а не операционки.

и естественно, любые библиотеки, в том числе и libc, из asm доступны

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

Если glibc использует то же расширение, то слив будет минимальным, чисто за счёт оверхеда.

Слив будет всегда, я тебе уже показал почему. Это будет либо мемкопи на rep movs, который сливает, либо тысячи проверок и портянка на как сейчас. И то она будет всегда сливать по определению, ибо нет серебрянной пули.

Ты знаешь, как твой код будет работать на первом AVX? Я знаю: он будет работать медленней SSE2.

Не будет.

8кб + 8кб - это половина L1D, или весь целиком, если HT включен. Эвиктится будет так, что свист стоять будет.

В чем конкретно будет свист? Конкретней - говори сразу в чем это выражается в примере «мемкопи». Толкать абстрактную муру нен адо.

Ты бредишь.

Конкретней, с цитатками желательно.

И? Ты про TLB-то понял?

Что я должен понять?

Троганье сколько-нибудь большого количества страничек выдавит код из STLB.

Без разницы.

В твоём случае, когда кода всего сотня байт, ничего страшного, но в нормальном продукте пенальти такое будет, что memcpy вдруг начнёт работать быстрее.

Т.е. типа много байт функция занимает?

http://pastebin.com/5sTNN6sb - вот тебе код memcpy() из глибц. Срываем покровы.

Твои рассуждения о нормальных продуктах смешны и лишь жалкие отговорки. У меня есть функция на 100байт - каким образом это что-то даст в твоём продукте, где на каждую функцию оверхед овер20байт? Темболее что в твоём понимании нормальный продукт?

Ну вот есть два лоад порта и один стор (до хасвелла, но мы ж про ВСЕГДА?).

И?

Если двигать данные, то писать получается в два раза медленней, чем читать.

Если копировать, представляешь, тоже. Только причем тут это? 2 функции в одинаковых условиях - одна работает быстрее - всё просто.

Есть один порт для XMM-арифметики. Если считать контрольную сумму на SSE, то упрётся всё в этот порт, а не в скорость фетча инструкций.

Какая контрольная сумма, пример - нет примера я сам его запилю за тебя. Мы это проверим.

rep movs работает медленней развёрнутой портянки только на netburst.

http://pastebin.com/79nKA3cP, http://pastebin.com/t5CaM5nb - твоя инфа настолько сотка, что у тебя сегодня целый день маленьких открытий.

Комментируй своё ВСЕГДА.

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

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

Слив будет всегда, я тебе уже показал почему. Это будет либо мемкопи на rep movs, который сливает, либо тысячи проверок и портянка на как сейчас. И то она будет всегда сливать по определению, ибо нет серебрянной пули.

На сколь-нибудь больших блоках производительность memcpy почти такая же, как у развёрнутого AVX. В отличие от последнего, memcpy будет работать с любыми входными параметрами.

И то, у меня в системе glibc 2.12, там AVX может и не быть.

Не будет.

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

В чем конкретно будет свист? Конкретней - говори сразу в чем это выражается в примере «мемкопи». Толкать абстрактную муру нен адо.

Из кэша будут вытеснятся полезные данные. Если процессор используется (помимо прочего), как универсальный data mover, то копирование вообще должно идти с nt-префетчем, и с nt-сторами.

Вот я тоже такой как увидел «неоптимальный» подсчёт контрольной суммы, сразу с шашкой бросился его оптимизировать. Само по себе оно отлично заработало, красивые графики построил, а как в систему встроил, так количество операций в секунду резко просело. Потому что кэш дерьмом ненужным забивался.

Т.е. типа много байт функция занимает?

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

Какая контрольная сумма, пример - нет примера я сам его запилю за тебя. Мы это проверим.

Да любая, хоть 16-битный xor для простоты возьми.

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

BLOCK SIZE: 1KB
64b x1 loop:
23.666636GB/s
64b x16 loop:
55.859934GB/s
rep movsq:
58.887361GB/s
memcpy:
55.909637GB/s
sse looped:
48.643713GB/s
sse unrolled:
106.925669GB/s
cachecp32:
66.807190GB/s
cachecp512:
113.478217GB/s

BLOCK SIZE: 8KB
64b x1 loop:
28.095306GB/s
64b x16 loop:
56.191776GB/s
rep movsq:
103.641506GB/s
memcpy:
101.008726GB/s
sse looped:
56.754691GB/s
sse unrolled:
114.796829GB/s
cachecp32:
103.900418GB/s
cachecp512:
115.663445GB/s

Как видишь, на более-менее длинных копированиях и memcpy, и rep movs почти такие же быстрые, как SSE2 или AVX.

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

Ты меня не слышишь.

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

Смотри, как забавно:

BLOCK SIZE: 131072KB
64b x1 loop:
10.447131GB/s
64b x16 loop:
10.452840GB/s
rep movsq:
14.648640GB/s
memcpy:
15.968835GB/s
sse looped:
10.298480GB/s
sse unrolled:
10.450298GB/s
cachecp32:
10.431209GB/s
cachecp512:
10.423024GB/s

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

На сколь-нибудь больших блоках производительность memcpy почти такая же, как у развёрнутого AVX. В отличие от последнего, memcpy будет работать с любыми входными параметрами.

Не такая же, далеко не такая же.

И то, у меня в системе glibc 2.12, там AVX может и не быть.

Да для памяти класть что там, хоть mmx.

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

Я не вижу причин для того, чтобы операция что-то там поменяла.

Из кэша будут вытеснятся полезные данные. Если процессор используется (помимо прочего), как универсальный data mover, то копирование вообще должно идти с nt-префетчем, и с nt-сторами.

Я это знаю, ты там наверное плохо прочитал навзание функции «cachecp» - она копирует кеш, и именно кеш. Для памяти специальный ntешный анрол. Я знаю что у меня в кеше и что мне надо копировать.

Щас там есть nt и лоады и сторы.

Вот я тоже такой как увидел «неоптимальный» подсчёт контрольной суммы, сразу с шашкой бросился его оптимизировать. Само по себе оно отлично заработало, красивые графики построил, а как в систему встроил, так количество операций в секунду резко просело. Потому что кэш дерьмом ненужным забивался.

Это отличается от того о чем говорю я - ты получил фейл, возможно даже из-за кеша. Только в моём случае ты фейл не получишь ну никак за редкими исключениями, но в этих исключениях за этим итак следят.

Я понимаю о чем ты говоришь, только это не тот случай.

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

Я понимаю всё, о чем ты говоришь, только это не тот случай - повторюсь. Если я во что-то упрусь - я подумаю над тем как сократить код.

Только это твой конкретно взятый случай, а про «вообще» говорить не надо.

Да любая, хоть 16-битный xor для простоты возьми.

sum = a1 ^ a2 ^ a3... Ты это понимаешь под хором?

Как видишь, на более-менее длинных копированиях и memcpy, и rep movs почти такие же быстрые, как SSE2 или AVX.

Как у тебя получилось, что 16байтные и 32байтные мувы читают из л1д с одинаковой скоростью? Это упомянутые табой халтурные avx1?

А теперь запусти это для памяти, я тебе показывал результаты с того же хасвела, где rep movs сливает в 2-3раза.

А теперь добавь в мемкопи без анрола какой-нибудь адд. Мемкопи - это просто пример, а rep movs - это просто читерство.

На л2 и далее разница будет менее заметна, но она будет и в купе с тремя инструкциями аркромя мува на мув - будет крайне заметна.

Поэтому ручной ананизм будет и это будет почти всегда быстрее, либо минимум так же, ибо штеуд по определению не может. Мне лень думать «а где-то там оно авось будет так же» и прочее. У меня есть факт - в 95% случаев анрол даёт профит каким бы «умным» штеуд небыл.

Когда там что-то куда-то не влезает - я за этим прослежу - не бойся.

Ты меня не слышишь.

Я слышу и понимаю тебя. Я не спорю с тобою, я не говорю: «тынеправ». Возможно для твоего случая анрол реально ничего не даёт, но ты слишком категорично это заявляешь. А это не модно.

anonymous
()
Ответ на: комментарий от mv

Значит это не нт, погляди в моих примерах - где я тестю блоки больше кеша - у меня нт.

void * cpyavx128(__m256i * to, __m256i * from, uint64_t n) {
  typeof(from) from_end = ((void *)from + n), ret = to;
  do {
    _mm256_stream_si256(to++, _mm256_stream_load_si256(from++));
    _mm256_stream_si256(to++, _mm256_stream_load_si256(from++));
    _mm256_stream_si256(to++, _mm256_stream_load_si256(from++));
    _mm256_stream_si256(to++, _mm256_stream_load_si256(from++));
  } while(from != from_end);
  return ret;
}

Разанроль копипастой на 32, 128, 512 и погляди. Мне прям интересно насколько сольёт твоя мемкопи.

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

Как у тебя получилось, что 16байтные и 32байтные мувы читают из л1д с одинаковой скоростью? Это упомянутые табой халтурные avx1?

Да, на SB и, ЕМНИП, IB avx не может широкий регистр за раз загрузить.

Хасвелла под рукой нет.

А теперь добавь в мемкопи без анрола какой-нибудь адд. Мемкопи - это просто пример, а rep movs - это просто читерство.

rep movs - это исконный для x86 способ копировать память. Он стал медленней работать, чем анролл, на четвёртом пне, но потом, как fast string operations появились, всё вернулось на свои места.

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

Ну я и не говорю, что онанизм бесполезен. Просто результат не всегда получается, какой ожидаешь. И даже если на 10% быстрее начинает работать для конкретного случая (выровненная на кэшлайн память, кратный 64/128/256/etc байт размер), то времени на это убьёшь больше, чем memcpy или rep movs использовать.

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

Я слышу и понимаю тебя. Я не спорю с тобою, я не говорю: «тынеправ». Возможно для твоего случая анрол реально ничего не даёт, но ты слишком категорично это заявляешь. А это не модно.

Ну вот и решили вопрос. Спрятали приборы, пожали руки, разошлись ;)

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

Да, на SB и, ЕМНИП, IB avx не может широкий регистр за раз загрузить.

Этож эпикфейл.

rep movs - это исконный для x86 способ копировать память. Он стал медленней работать, чем анролл, на четвёртом пне, но потом, как fast string operations появились, всё вернулось на свои места.

Ну не совсем.

Ну я и не говорю, что онанизм бесполезен. Просто результат не всегда получается, какой ожидаешь.

Молодец. Если ты знаешь что делаешь - всегда, даже какой-то фейл всегда ожидаем и исправляем. Не форфан же леплю.

И даже если на 10% быстрее начинает работать для конкретного случая (выровненная на кэшлайн память, кратный 64/128/256/etc байт размер)

Дак в этом суть, никто не онанизмом не занимает ради чего-то мистического. У меня есть конкретный случай - для него и фагачу.

то времени на это убьёшь больше, чем memcpy или rep movs использовать.

Суть не в мемкопи - суть в любом обходе памяти/кеша. И готового почти всегда нет, а если мне покласть - я заюзаю мемкопи, да и мемкопи на gcc пишется за 2секунды, а анролится копипастой.

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

Онанизмом занимаются не форфан, а для чего-то.

Ну вот и решили вопрос. Спрятали приборы, пожали руки, разошлись ;)

Зачем расходится - мне интересен ответ на коммент выше.

anonymous
()
Ответ на: комментарий от anonymous
BLOCK SIZE: 131072KB
64b x1 nt loop:
15.323934GB/s
cpyavx128:
15.712882GB/s
rep movs:
13.925486GB/s
memcpy:
15.653819GB/s

Первый - это:

    asm volatile (
        "1:\n"
        "movq (%%rsi), %%rax\n"
        "movnti %%rax, (%%rdi)\n"
        "add $8, %%rsi\n"
        "add $8, %%rdi\n"
        "dec %%edx\n"
        "jnz 1b\n"
        :
        : "D"(to), "S"(from), "d"(n/8));

16 гиг/с - это на моём 3770K предел.

mv ★★★★★
()
Ответ на: комментарий от mv
BLOCK SIZE: 131072KB
cpyavx32:
26.208782GB/s
cpymv:
25.396852GB/s

Ну где-то на уровне всех, а вот avx32 без анролла работает на удивление быстро - т.е. на уровне фулланрола, а вот sse16 рабоает намного медленней твоей портянки на movnti - возможно это мистический лсд, либо халтурные симды. Есть идеи почему так?

void * cpavx32(__m256i * to, __m256i * from, uint64_t n) {
  typeof(from) from_end = ((void *)from + n), ret = to;
  do {
    _mm256_stream_si256(to++, _mm256_stream_load_si256(from++));
  } while(from != from_end);
  return ret;
}

Наудивление, но рекордсмен. Твоё правило для avx2 и оперативы похоже работает.

anonymous
()
Ответ на: комментарий от IvanR

для этого ничего не нужно кроме возможности писать в «файл» бинарные_байты текстовые печатные символы«зависяший от целевой платформы набор бинарных лексем чей словарь основанный на алфавите на этих лексемах генерирует содержит в себе слова исполнение которых перечесляет любое бинарную последовательность»

qulinxao ★★☆
()

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

ckotinko ☆☆☆
()
Ответ на: комментарий от emulek

за чем ты тогда упомянул C++

ознакомся , что ли с святым Страустропа мнением о

ООП было важно при создании С++, теперь и в дальнейшем С++ «мультифиговый» в отличии от первоночальной «оппфиговости» которая и так была сильно покоцана для С-совместности.

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

указатели как были так и остались

а вот лексема которая ранее была всегда оператором доступа к смещению по указателю ( т.е a->b есть всегда (*a)[смещ_b] по размеру поля b) стала просто обычным перегружаемым оператором (привет алгол68)

кто бездумно нагружает тот же + не коммутатирующей тот ссзб.

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

а вот sse16 рабоает намного медленней твоей портянки на movnti - возможно это мистический лсд, либо халтурные симды. Есть идеи почему так?

movnti, cpyavx128, cpysse16:

[vitaly@gravicappa tmp]$ gcc -o foo foo.c -O2 -lgomp -mavx
[vitaly@gravicappa tmp]$ perf stat -ddd ./foo

BLOCK SIZE: 131072KB
64b x1 nt loop:
14.787453GB/s

 Performance counter stats for './foo':

      17317.784073 task-clock                #    0.999 CPUs utilized          
             1,754 context-switches          #    0.101 K/sec                  
                 5 cpu-migrations            #    0.000 K/sec                  
               184 page-faults               #    0.011 K/sec                  
    67,286,170,277 cycles                    #    3.885 GHz                     [28.57%]
    32,765,884,189 stalled-cycles-frontend   #   48.70% frontend cycles idle    [28.57%]
   <not supported> stalled-cycles-backend  
   103,238,691,165 instructions              #    1.53  insns per cycle        
                                             #    0.32  stalled cycles per insn [35.72%]
    17,202,484,799 branches                  #  993.342 M/sec                   [35.71%]
           109,230 branch-misses             #    0.00% of all branches         [35.73%]
    17,197,298,182 L1-dcache-loads           #  993.043 M/sec                   [35.72%]
     2,154,860,034 L1-dcache-load-misses     #   12.53% of all L1-dcache hits   [35.73%]
     2,469,283,516 LLC-loads                 #  142.587 M/sec                   [28.57%]
   <not supported> LLC-load-misses:HG      
   <not supported> L1-icache-loads         
         2,800,233 L1-icache-load-misses     #    0.00% of all L1-icache hits   [28.58%]
    17,182,029,366 dTLB-loads                #  992.161 M/sec                   [28.58%]
                 0 dTLB-load-misses          #    0.00% of all dTLB cache hits  [28.58%]
            20,056 iTLB-loads                #    0.001 M/sec                   [28.58%]
           136,595 iTLB-load-misses          #  681.07% of all iTLB cache hits  [28.58%]
   <not supported> L1-dcache-prefetches    
       512,714,988 L1-dcache-prefetch-misses #   29.606 M/sec                   [28.57%]

      17.335135056 seconds time elapsed

[vitaly@gravicappa tmp]$ gcc -o foo foo.c -O2 -lgomp -mavx
[vitaly@gravicappa tmp]$ perf stat -ddd ./foo

BLOCK SIZE: 131072KB
cpyavx128:
15.261367GB/s

 Performance counter stats for './foo':

      16777.390797 task-clock                #    0.999 CPUs utilized          
             1,699 context-switches          #    0.101 K/sec                  
                 5 cpu-migrations            #    0.000 K/sec                  
               183 page-faults               #    0.011 K/sec                  
    65,106,475,714 cycles                    #    3.881 GHz                     [28.57%]
    61,818,863,230 stalled-cycles-frontend   #   94.95% frontend cycles idle    [28.58%]
   <not supported> stalled-cycles-backend  
    12,962,486,392 instructions              #    0.20  insns per cycle        
                                             #    4.77  stalled cycles per insn [35.72%]
     1,088,153,021 branches                  #   64.858 M/sec                   [35.71%]
            96,005 branch-misses             #    0.01% of all branches         [35.73%]
     4,320,438,112 L1-dcache-loads           #  257.515 M/sec                   [35.73%]
     2,157,096,515 L1-dcache-load-misses     #   49.93% of all L1-dcache hits   [35.74%]
     2,806,651,648 LLC-loads                 #  167.288 M/sec                   [28.59%]
   <not supported> LLC-load-misses:HG      
   <not supported> L1-icache-loads         
         2,683,701 L1-icache-load-misses     #    0.00% of all L1-icache hits   [28.58%]
     4,321,854,107 dTLB-loads                #  257.600 M/sec                   [28.58%]
                 0 dTLB-load-misses          #    0.00% of all dTLB cache hits  [28.57%]
            21,582 iTLB-loads                #    0.001 M/sec                   [28.57%]
            15,555 iTLB-load-misses          #   72.07% of all iTLB cache hits  [28.56%]
   <not supported> L1-dcache-prefetches    
       247,270,000 L1-dcache-prefetch-misses #   14.738 M/sec                   [28.56%]

      16.795201958 seconds time elapsed

[vitaly@gravicappa tmp]$ gcc -o foo foo.c -O2 -lgomp -mavx
[vitaly@gravicappa tmp]$ perf stat -ddd ./foo

BLOCK SIZE: 131072KB
sse looped:
9.730732GB/s

 Performance counter stats for './foo':

      26304.242260 task-clock                #    0.999 CPUs utilized          
             2,665 context-switches          #    0.101 K/sec                  
                 1 cpu-migrations            #    0.000 K/sec                  
               182 page-faults               #    0.007 K/sec                  
   102,020,591,197 cycles                    #    3.878 GHz                     [28.56%]
    84,500,142,496 stalled-cycles-frontend   #   82.83% frontend cycles idle    [28.56%]
   <not supported> stalled-cycles-backend  
    51,648,918,172 instructions              #    0.51  insns per cycle        
                                             #    1.64  stalled cycles per insn [35.69%]
     8,612,041,189 branches                  #  327.401 M/sec                   [35.71%]
           152,625 branch-misses             #    0.00% of all branches         [35.71%]
     8,620,960,743 L1-dcache-loads           #  327.740 M/sec                   [35.73%]
     4,303,924,814 L1-dcache-load-misses     #   49.92% of all L1-dcache hits   [35.72%]
     3,215,757,338 LLC-loads                 #  122.252 M/sec                   [28.58%]
   <not supported> LLC-load-misses:HG      
   <not supported> L1-icache-loads         
         5,369,346 L1-icache-load-misses     #    0.00% of all L1-icache hits   [28.58%]
     8,632,330,804 dTLB-loads                #  328.173 M/sec                   [28.58%]
                 0 dTLB-load-misses          #    0.00% of all dTLB cache hits  [28.58%]
            26,453 iTLB-loads                #    0.001 M/sec                   [28.58%]
            24,655 iTLB-load-misses          #   93.20% of all iTLB cache hits  [28.57%]
   <not supported> L1-dcache-prefetches    
       340,054,637 L1-dcache-prefetch-misses #   12.928 M/sec                   [28.57%]

      26.332138232 seconds time elapsed
При копировании на целочисленном регистре IPC в три раза больше, чем на SSE2. На AVX ещё меньше, но там execution path другой - wide load работает.

Я думаю, что для SSE переименования регистров нет, поэтому всё сериализуется и на одном порте работает. А целочисленных параллельно два или три штуки летят, доступный для ядра канал памяти раньше забивается.

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

пользоваться асмом не надо,

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

но понимать основы на уровне 486-первопень-второпень надо

Лучше не надо, первопень протух и не актуален, х86 сейчас нихрена даже близко не похож первопень. А уж вменяемой теории по первопню он сейчас врядли найдёт - это всё мифы и легенды с днища окияна. Лучше быть нулёвым, чем с протухшей теорией основанной на мифах и легендах соседей по парте и башкой забитой говном - это будет десятый drBatty.

Что даст тебе понимание на уровне первопня? Ничего - http://rus-linux.net/lib.php?name=/MyLDP/hard/memory/memory.html - лучше пусть это прочитает и осилит, а потом ещё чуть поглубже. Потом мануал по штеуду. Это примерно в бесконечность полезней. Сейчас же чтобы хоть чутка был профит от хардварной матчасти - ты должен быть илитой илит, в противном случае это не работает и только вредно, ибо это не примитивный первопень.

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

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

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

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

ckotinko ☆☆☆
()
Ответ на: комментарий от ckotinko

в большинстве случаев не должен.

Инфа сотка.

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

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

Твои познания настолько протухли - пример первопня в действии.

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

Знание первопня ненужны ну никак - это твоя бредня. Это примерно как знание какой-нибудь протухшей в 80-х 8-мибитки. Совместимость с первопнём осталась на уровне инструкций и то условная - в остальном никаких сходсв нет.

anonymous
()
Ответ на: комментарий от qulinxao

ознакомся , что ли с святым Страустропа мнением о ООП было важно при создании С++, теперь и в дальнейшем С++ «мультифиговый» в отличии от первоночальной «оппфиговости» которая и так была сильно покоцана для С-совместности.

я в курсе. Но есть одно маленькое «но», которое ты не учитываешь: вся эта твоя «C-совместимость» на самом деле — шелуха. Тащить её в свой код или нет — решать исключительно тебе. Если ты хочешь, что-бы operator= побитно копировал как в сишечке — он будет так делать. Просто НЕ определяй operator=, и эта вся шелуха попадёт в твой код.

Или будь мужиком, и определи так, как тебе нужно, и не ной про «сишечность».

emulek
()
Ответ на: комментарий от qulinxao

указатели как были так и остались

только на int, или на те классы, в которых ты не осилил это определить.

а вот лексема которая ранее была всегда оператором доступа к смещению по указателю ( т.е a->b есть всегда (*a)[смещ_b] по размеру поля b) стала просто обычным перегружаемым оператором (привет алгол68)

повторяю: ВСЁ перегружается. Кроме точки. У тебя это твоё (*a) тоже перегружается.

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

у С-рупа 4 буклета:

Бьярне Страуструп Программирование: принципы и практика использования C++, исправленное издание = Programming: Principles and Practice Using C++. — М.: «Вильямс», 2011. — С. 1248. — ISBN 978-5-8459-1705-8 The C++ Programming Language by Bjarne Stroustrup — Addison–Wesley Pub Co; 3rd edition (February 15, 2000); ISBN 0-201-70073-5 The Design and Evolution of C++ by Bjarne Stroustrup — Addison–Wesley Pub Co; 1st edition (March 29, 1994); ISBN 0-201-54330-3 The Annotated C++ Reference Manual by Margaret A. Ellis & Bjarne Stroustrup — Addison–Wesley Pub Co; (January 1, 1990); ISBN 0-201-51459-1

Programming: Principles and Practice Using C++ by Bjarne Stroustrup – Addison-Wesley Professional; 1st edition (29 December 2008); ISBN 0-321-54372-6 The C++ Programming Language by Bjarne Stroustrup – Addison-Wesley Pub Co; 4th edition (23 May 2013); ISBN 0-321-563840 The Design and Evolution of C++ by Bjarne Stroustrup – Addison-Wesley Pub Co; 1st edition (29 March 1994); ISBN 0-201-54330-3 The Annotated C++ Reference Manual by Margaret A. Ellis & Bjarne Stroustrup – Addison-Wesley Pub Co; (1 January 1990); ISBN 0-201-51459-1

а фортранить можеш на чём угодно.

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

первопень протух и не актуален, х86 сейчас нихрена даже близко не похож первопень.

это как «демократия». Да, в «стране эльфов» сейчас не демократия. Однако, сами эльфы думают, что демократия это «XYZ», и у них «XYZ», которую они называют «демократия». Потому в стране эльфов, с точки зрения эльфов, таки демократия.

это всё мифы и легенды с днища окияна.

код пишут ориентируясь на эти мифы, и разработчики процессоров вынужденны делать процессоры, которые выполняют эту хотелку. Если 95% быдлокодеров уверены, что правильнее выполнять XOR AX,AX вместо MOV AX,0, то почему-бы это не реализовать? Получается-то побыстрее...

Лучше быть нулёвым, чем с протухшей теорией основанной на мифах и легендах соседей по парте и башкой забитой говном - это будет десятый drBatty.

drBatty в курсе, что легенды это легенды. Но легенды IRL работают таки быстрее.

Что даст тебе понимание на уровне первопня? Ничего

а у тебя-то оно есть?

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

указатели как были так и остались

только на int, или на те классы, в которых ты не осилил это определить.

а вот лексема которая ранее была всегда оператором доступа к смещению по указателю ( т.е a->b есть всегда (*a)[смещ_b] по размеру поля b) стала просто обычным перегружаемым оператором (привет алгол68)

повторяю: ВСЁ перегружается. Кроме точки. У тебя это твоё (*a) тоже перегружается.

обозначил тебе в каком контектсе ты «открываеш глаза»

возможность сделать U не есть обязаность делать U

а вот «злоупотреблять » сменной денотатов , есть снижение информативности.

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

обозначил тебе в каком контектсе ты «открываеш глаза»

с тобой спорить бесполезно. Ты говоришь «это чёрное», я доказываю, что это зелёное. Ты сливашь с «емулек познаёт мир, он узнал, что зелёное == зелёное».

emulek
()
Ответ на: комментарий от qulinxao

я не вижу связи твоего коммента со своим постом. Что ты хотел сказать-то?

emulek
()
Ответ на: комментарий от anonymous

ты чо, бро, идейный программист на ассемблере? зачем такую ерунду жжошь*

ckotinko ☆☆☆
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.