Свежие комментарии

Title Comment
Сейчас память подорожала

Сейчас память подорожала заметно (смотрел цену на DDR3 - процентов на 30-40) и похоже что дешевая быстрее.

Т.е. 4x16 не только с радиатором, но и кулером отдельным - стоила ну в пределах 10% разницы относительно 2400 приличного производителя (т.е. не хрен с горы неясный, а там Samsung/crucial и прочие подобные слова). Ну то есть это конкретный корсар на самом деле был дешевым, потому что можно было найти и еще подороже раза в полтора.

Да, похоже на то. Интересно,

Да, похоже на то. Интересно, можно ли упаковать в AVX лучше, чем написал...

Вот Агнер наш Фог пишет, что

Вот Агнер наш Фог пишет, что insertf128 - вообще два такта. А sub/mul - по одному, вестимо.

А вообще, вот у тебя в случае

А вообще, вот у тебя в случае AVX+SSE (относительно SSE)
- две лишних упаковки
- но зато ты sub/mul делаешь с длинными векторами т.е. два действия вместо четырех.

Поди, одно аккурат стоит другого, два действия поэкономил, два добавил?

Когда я покупал разница на 8G

Когда я покупал разница на 8G модули была раза в полтора! 3200 все уже считались оверклокерскими, с радиаторами, красивой упаковкой, такое.

(3200 и 2400 стоят сейчас

(3200 и 2400 стоят сейчас одинаково).

Если в кэш, то не надо stream_ps.

Именно этот код (не повезло

Именно этот код (не повезло ему) был вообще неправильным. Я перемерял правильно, с cvt, и результаты с точностью до статпогрешности те же. Ничего конверсия не стоит, не в ней дело.

А битовая магия выглядит так же только там вместо старших нулей всё пакуется константой 0x4700 во-первых и множитель другой во-вторых. Т.е. с точки зрения паковки и mul-sub всё в точногсти так же, только константы другие (и каст вместо конверсии).

Ну, у меня всё в кэш лезет.

Ну, у меня всё в кэш лезет. Мегабайт байтов, соответственно 4 мегабайта флотов, по кругу. Если я побольше данных сделаю всё в DDR4-2400 упрётся (да, я не так богат что бы 3200), это понятно.

Это-та скорость меня устраивает, вопрос как из AVX простого выжать похожее.

Я про cast вообще не понял.

Я про cast вообще не понял.
Или битовая магия (cast + sub), или cvttps_epi32
А одного каста - мало ж.

Ну от 36GB/sec out + 9GB/sec

Ну от 36GB/sec out + 9GB/sec in - это, поди, память насытилась уже, больше нету?
Во всяком случае похоже же, у меня DDR4-3200 вот в районе 45Gb/sec вроде и есть.

stream_ps() вместо store_ps() может несколько ускорить.

Тааак, это я накопипастил

Тааак, это я накопипастил криво, из варианта с битовой магией вместо castsi256(). Не то, короче, скопипастил. И, кажется, померял какую-то лажу. Ща буду перемеривать. Хотя битовая магия вообще ничего не даёт, никакого выигрыша против castsi256

Ну и на минуточку, а где

Ну и на минуточку, а где собственно преобразование int-float?

Сразу в 256 бит распаковывать

Сразу в 256 бит распаковывать можно только в AVX2 (_mm256_unpack{hi|lo}_epi{8|16}()) — или я не понимаю как. Если подскажешь буду благодарен.

ключи для avx "-O3 -mfpmath=sse -ffast-math -mavx" и код с v в начале, да:

  3c:   c5 e9 60 c4             vpunpcklbw %xmm4,%xmm2,%xmm0
  40:   c5 e9 68 d4             vpunpckhbw %xmm4,%xmm2,%xmm2
  44:   c5 f9 61 cb             vpunpcklwd %xmm3,%xmm0,%xmm1
  48:   c5 f9 69 fb             vpunpckhwd %xmm3,%xmm0,%xmm7
  4c:   c5 e9 61 c3             vpunpcklwd %xmm3,%xmm2,%xmm0
  50:   c5 e9 69 d3             vpunpckhwd %xmm3,%xmm2,%xmm2
  54:   c4 e3 75 18 cf 01       vinsertf128 $0x1,%xmm7,%ymm1,%ymm1
  5a:   c4 e3 7d 18 c2 01       vinsertf128 $0x1,%xmm2,%ymm0,%ymm0

9G/sec это семплы. Т.е. 9G байтов переаботано в 9G флоатов (36G байтов, соотвественно).

А вот ключи у компилятора

А вот ключи у компилятора какие, там _mm_unpacklo_epi16 (к примеру) транслируется в VPUNPCKLWD или без V?
если без, то вот и этот самый микс.
Вообще, я не понимаю зачем читать-распаковывать по 128 бит, а потом сливать в 256. Кто не дает сразу 256?

И, кстати, 9G/sec - это в каких единицах, входной поток или выходной?

vzeroupper не делается, но

vzeroupper не делается, но там вообще распаковка адовая получается:
                const __m128i mem0 = _mm_load_si128((__m128i*)from);
               
                const __m128i tmp16l = _mm_unpacklo_epi8(mem0, zero);
                const __m128i tmp16h = _mm_unpackhi_epi8(mem0, zero);

                const __m128i tmp32ll = _mm_unpacklo_epi16(tmp16l, zero);
                const __m128i tmp32hl = _mm_unpackhi_epi16(tmp16l, zero);
               
                const __m128i tmp32lh = _mm_unpacklo_epi16(tmp16h, zero);
                const __m128i tmp32hh = _mm_unpackhi_epi16(tmp16h, zero);
               
                const __m256i tmp0 = _mm256_insertf128_si256(zero256, tmp32ll, 0);
                const __m256i tmp1 = _mm256_insertf128_si256(zero256, tmp32lh, 0);

                const __m256 in0 = _mm256_castsi256_ps(_mm256_insertf128_si256(tmp0, tmp32hl, 1));
                const __m256 in1 = _mm256_castsi256_ps(_mm256_insertf128_si256(tmp1, tmp32hh, 1));

                const __m256 out0 = _mm256_sub_ps(_mm256_mul_ps(in0, mul), del);
                const __m256 out1 = _mm256_sub_ps(_mm256_mul_ps(in1, mul), del);

                /* Store 16 floats */
                _mm256_store_ps(to,      out0);
                _mm256_store_ps(to +  8, out1);
               
                count -= 16;
                from += 16;
                to += 16;
Куда его тут? Да, я ещё интерливинг пытался тут вставить (ну типа как половина данных готова так с ними и работать а не групировать операции по смыслу как я тут скопипастил) и удвоить объём работы в одном проходе цикла (тоже как с группировкой по смыслу так и сгруппировкой по локальности данных) и то и другое даёт изменнеия в пределах статпогрещности. Да, в этом коде zero, zero256, mul, del — константы, понятно. Нули, множитель (512/255) и просто 1 в соотвествующих веторах.

Таблица! Это было первое, что я попытался сделать. Это медленней в 2-3 раза чем следующий самый медленный вариант!

"что, например, с AVX всё

"что, например, с AVX всё равно лучше SSE2"

vzeroupper делается? Там переход AVX/SSE очень дорогой (без явного обнуления), т.е. ради пары инструкций оно того не стоит.

Ну и второй вопрос, а вот если входных значений всего 256, то таблица не быстрее?

А можно тебя помучать про SIMD?

Я тут пытаюсь нащупать лучший способ сделать из массива байтов (т.е. целых чисел в диапазоне [0..255]) массив float'ов (32-ъх битных IEEE754) в диапазоне [-1.0..1.0] — т.е. с рескейлом и сдвигом. Смотрю я на варианты «что угодно», SSE4 (ведь нет уже живого железа без него? SSE3 это первый Core!), AVX1, AVX2+FMA (потому что, кажется, AVX2 без FMA3 не бывает). Смотрю на SkyLake (i7-6700K зажатый ровно на 40, что бы никакие трубобусты мне бенчмарки не пачкали). А, да, gcc 6.3.0 и clang 3.9.1 дают качественно одинаковые результаты. И нахожусь в некотором недоумении.

(1) Если разрешить -mavx2 -mfma3, то код писать вообще не надо. В смысле, тупой цикл по 1 элементу зараз на plain С с одним умножением и одним вычитанием даёт чуть больше 9G в секунду на 4GHz проце. Компилятор развернул и векторизовал ВСЁ. Я не смог написать руками лучше, хотя пытался раз 5. Мой лучший ручной результат с AVX2 — 8G в секунду.

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

Что меня удивляет (кроме ума компилятора): что, например, с AVX всё равно лучше SSE2. Т.е. пока у нас нет FMA и, главное, _mm256_unpack{hi|lo}_epi{8|16}, от 256-битных регистров тут толку нет.

Это я что-то не так делаю? Ну не верю я, что такая типовая на вид задача не может выиграть от AVX, только от AVX2 :)

И, кстати, какова твоя статистика (есть ли она у тебя) с какого SSE можно начинать что бы уже никого по сути не обидеть?

В 1.3. - нет, потому что вот

В 1.3. - нет, потому что вот вся работа с метадатой доживает последние релизы и в 1.4 будет сильно другой.

Когда будут беты-рц 1.4 - попросите еще раз, подумаем как оно ляжет на новые идеи.

Жаловаться не на что, но, вот

Жаловаться не на что, но, вот, есть хотелка (пока вы с ориентацией воюете ещё): можно ли сделать одноразовый (как экспокоррекция при выключенном XMP) поворот (ну и зеркало до кучи)? Бывает, нужно повернуть фото для анализа и приходится включать запись XMP, чтобы воспользоваться этими функциями. Или не одноразовый, а "до закрытия" или "до перехода в другой фолдер" хранить в памяти.

Ну вот меня - еще не

Ну вот меня - еще не настолько.

Тем более, что все в 19 не нафигачишь, ну вот куда деть клавиатурный кабель? Он 2-метровый, а от клавиатуры до монитора - ну полметра. Ну вот только в клубок и проволочкой.

Пятый. Шансов, я думаю, мало.

Пятый. Шансов, я думаю, мало.

Займу очередь.

Собственно займу тоже очередь за ним. ( Москва же? )

А мну это все настолько

А мну это все настолько достало как-то раз, что я купил две 19" PDUшки, отболгарил от ненужных 19" органайзеров уши и приболтовал все это величие к стене за столом так, что его не видно и я как бы в домике. Жена может теперь невозбранно шарить шваброй в святая святых, правда, почему-то делает это как-то с опаской, видимо рефлекс наработался :)

Заберу монитор

Хочу ваш монитор

будете уже третьим. Первый -

будете уже третьим. Первый - уволок сегодня примерять (ему тут улицу перейти), если не войдет ему в стол - вернет.

Ну вот я креплением

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

В Москву не поеду.

Заманчиво...!

/странно видеть паутину из проводов (хотя мне тоже не удаётся поддерживать порядок "за столом" дольше двух недель (за полгода))/

Аыы..

Аыы..

Постою в очереди, например.

Но мысль-то понятная?

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

Таймаут не мерял, но должен

Таймаут не мерял, но должен быть маленький.

Pages

Subscribe to comments_recent_new