LINUX.ORG.RU

Как можно затюнинговать этот участок кода?

 , , ,


4

13

Я не програмист и С знаю достаточно плохо, но вот тут хочеться разобраться и попытаться оптимизировать этот участок. Это код из gstreamer, который участвует в перегоне RGB в UYV http://cgit.freedesktop.org/gstreamer/gst-plugins-base/tree/gst/videoconvert/...

#define SCALE    (8)
#define SCALE_F  ((float) (1 << SCALE))

static void
videoconvert_convert_matrix8 (VideoConvert * convert, gpointer pixels)
{
  int i;
  int r, g, b;
  int y, u, v;
  guint8 *p = pixels;

  for (i = 0; i < convert->width; i++) {
    r = p[i * 4 + 1];
    g = p[i * 4 + 2];
    b = p[i * 4 + 3];

    y = (convert->cmatrix[0][0] * r + convert->cmatrix[0][1] * g +
        convert->cmatrix[0][2] * b + convert->cmatrix[0][3]) >> SCALE;
    u = (convert->cmatrix[1][0] * r + convert->cmatrix[1][1] * g +
        convert->cmatrix[1][2] * b + convert->cmatrix[1][3]) >> SCALE;
    v = (convert->cmatrix[2][0] * r + convert->cmatrix[2][1] * g +
        convert->cmatrix[2][2] * b + convert->cmatrix[2][3]) >> SCALE;

    p[i * 4 + 1] = CLAMP (y, 0, 255);
    p[i * 4 + 2] = CLAMP (u, 0, 255);
    p[i * 4 + 3] = CLAMP (v, 0, 255);
  }
}

При записи скринкаста в фуллхд videoconvert_convert_matrix8 жрет нереально много времени. Может чей-то опытый глаз поможет, хоть напрвит в сторону чего тут можно оптимизировать. например i * 4 повторяеться 6 раз, хотя понимаю что оно то почти и не дает нагрузку.

★★★★★

Последнее исправление: cetjs2 (всего исправлений: 3)
Ответ на: комментарий от Novell-ch

так он и используется

Чёт я не заметил, да он там есть в этом модуле - надо было полистать ниже - это ещё проще.

только профит не видет, или может без него еше медленее

А для rgb_to_yuv его нет, поэтому он и не юзается в данном случае - надо будет запилить.

Както так:

 23,88%  libgstvideoconvert.so        [.] videoconvert_convert_matrix8
 19,78%  libgstvideo-1.0.so.0.204.0   [.] video_orc_pack_NV12
 17,42%  libgstvideo-1.0.so.0.204.0   [.] video_chroma_down_v2_guint8
 17,28%  libgstvideo-1.0.so.0.204.0   [.] video_orc_unpack_BGRA
 15,64%  libgstvideo-1.0.so.0.204.0   [.] video_chroma_down_h2_guint8
  0,71%  libgstximagesrc.so           [.] gst_ximage_src_ximage_get
  0,56%  i965_drv_video.so            [.] gen7_vme_walker_fill_vme_batchbuffer
  0,55%  libgstvideoconvert.so        [.] videoconvert_convert_generic

Надо сделать так же, как в ssr - написать полный BGRA_to_NV12 и выпилить всю эту байду.

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

ну для частного случая как вот захват экрана оно подойдет, но потом они скажут что у нас кросплатформа, и videoconvert не только для BGRA_to_NV12. Тут разве что просто написать свой плагин, и втыкать его в пайпы вместо videoconvert. Полистав рассылку нашел жалобы на тот же videoconvert, что начало дико тормозить при переходе с 0.10 где ffmpegcolorspace к 1.0 где уже videoconvert, взяли бы табличную хоть и то было бы счастье.

Novell-ch ★★★★★
() автор топика
Ответ на: комментарий от Novell-ch

ну для частного случая как вот захват экрана оно подойдет,

Не, не - там всё норм.

Там есть возможность сделать свою функцию и положить её в:

static const VideoTransform transforms[]

if (!videoconvert_convert_lookup_fastpath (convert)) {
    convert->convert = videoconvert_convert_generic;
    if (!videoconvert_convert_compute_matrix (convert))
      goto no_convert;

    if (!videoconvert_convert_compute_resample (convert))
      goto no_convert;
  }

Эта функция ищет в таблице подходящий конвертер:

videoconvert_convert_lookup_fastpath(convert)

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

А вот если сделать RGB_to_yuv конвертер отдельно - его скорее всего примут.

Как этот:

{GST_VIDEO_FORMAT_AYUV, GST_VIDEO_COLOR_MATRIX_BT601, GST_VIDEO_FORMAT_xRGB,
      GST_VIDEO_COLOR_MATRIX_RGB, FALSE, TRUE, 0, 0, convert_AYUV_ARGB}

Посмотри.

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

Мне тут было нефиг делать - http://pastebin.com/dQHwDSb2

Мне было лень пилить - я взял от ssr ради теста - работает. 420 более вменяемый, чем NV12. Насколько я понял в 420-м формат yyyyyyyyuuvv, а в NV12 yyyyyyyyuvuv.

gst-launch-1.0  -e matroskamux name=muxer ! filesink location=test.mkv  ximagesrc use-damage=0 ! videoconvert ! video/x-raw,format=I420,framerate=25/1 ! vaapiencode_h264 ! muxer.video_0 
//
0,032 CPUs utilized 

Теперь осталось разобраться в орке и запилить это на орке, а так же надо сделать на орке умножение «на матрицу». И будет всё «круто».

Так же можно ещё сделать сделать BGRx -> NV12.

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

Вот теперь оно реально почти не жрёт цпу.

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

Спасибо, реально стало 0.054 CPUs utilized, пачт на 1.2.4 не наложился чуть пришлось подправить, ну а что нет NV12 жалко, оно нужно для радеонов, хотя не думаю что кроме разработчиков месы в мире есть хоть 10 человек которые исползуют сейчас gst-omx для радеонов.

Novell-ch ★★★★★
() автор топика
Ответ на: комментарий от anonymous

пачт хороший, я получил 0.259 CPUs utilized, в общем не плохо. Считай в 2 раза маньше чем по умолчанию.

Novell-ch ★★★★★
() автор топика
Ответ на: комментарий от Novell-ch

Спасибо, реально стало 0.054 CPUs utilized

Оно далеко не в память упирается, плюс у тебя нет авх2. Так будет все 0.015.

пачт на 1.2.4 не наложился чуть пришлось подправить

Да, он на гит.

ну а что нет NV12 жалко

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

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

Они наверное просто не осилили написать videoconvert_convert_matrix8() на орке. А этот орк, этот орк. Я всё не престаю удивляться тому говну, что изрыгает обезьяна, когда её допустили до программирования.

Я не представляю вообще как написать на этом «языке» что-то, кроме бесполезного говна.

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

«мы гинерируем функции в рантайме с оптимизацией ко-ко-ко», дак так, как вы их гинерируете - лучше вообще не гинерировать.

У меня нет слов из-за лютой ненависти. Просто обезьяны.

anonymous
()

Ребят, все совершенно неверно.

Если не жалко дополнительно выделить 2^(8*3) памяти (что равно 16 мб), то можно закешировать значения всех цветов в отдельную структуру и просто их выдирать потом.

Deleted
()

Я взял твой патч из SRPM-ки и наложил на SRPM из репозитория packman. Не компилируется:

make -C videoconvert
make[3]: Entering directory `/home/zenitur/rpmbuild/BUILD/gst-plugins-base-1.2.4/gst/videoconvert'
  CP     tmp-orc.c
  CP     gstvideoconvertorc.h
make  all-am
make[4]: Entering directory `/home/zenitur/rpmbuild/BUILD/gst-plugins-base-1.2.4/gst/videoconvert'
  CC       libgstvideoconvert_la-gstvideoconvert.lo
  CC       libgstvideoconvert_la-videoconvert.lo
In file included from videoconvert.c:1223:0:
/usr/lib64/gcc/x86_64-suse-linux/4.7/include/pmmintrin.h:32:3: error: #error "SSE3 instruction set not enabled"
In file included from videoconvert.c:1224:0:
/usr/lib64/gcc/x86_64-suse-linux/4.7/include/tmmintrin.h:31:3: error: #error "SSSE3 instruction set not enabled"
videoconvert.c:1251:6: warning: no previous prototype for 'Convert_BGRA_YUV420_SSSE3' [-Wmissing-prototypes]
videoconvert.c: In function 'Convert_BGRA_YUV420_SSSE3':
videoconvert.c:1288:32: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
videoconvert.c:1290:32: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
videoconvert.c:1291:32: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
videoconvert.c:1292:32: warning: implicit declaration of function '_mm_shuffle_epi8' [-Wimplicit-function-declaration]
videoconvert.c:1292:32: warning: nested extern declaration of '_mm_shuffle_epi8' [-Wnested-externs]
videoconvert.c:1292:32: error: incompatible type for argument 1 of '_mm_or_si128'
In file included from /usr/lib64/gcc/x86_64-suse-linux/4.7/include/xmmintrin.h:1247:0,
                 from videoconvert.c:1221:
/usr/lib64/gcc/x86_64-suse-linux/4.7/include/emmintrin.h:1243:1: note: expected '__m128i' but argument is of type 'int'
videoconvert.c:1292:32: error: incompatible type for argument 2 of '_mm_or_si128'
In file included from /usr/lib64/gcc/x86_64-suse-linux/4.7/include/xmmintrin.h:1247:0,
                 from videoconvert.c:1221:
/usr/lib64/gcc/x86_64-suse-linux/4.7/include/emmintrin.h:1243:1: note: expected '__m128i' but argument is of type 'int'
videoconvert.c:1295:32: warning: implicit declaration of function '_mm_hadd_epi32' [-Wimplicit-function-declaration]
videoconvert.c:1295:32: warning: nested extern declaration of '_mm_hadd_epi32' [-Wnested-externs]
videoconvert.c:1295:35: error: incompatible types when assigning to type '__m128i' from type 'int'
videoconvert.c:1296:35: error: incompatible types when assigning to type '__m128i' from type 'int'
videoconvert.c:1297:35: error: incompatible types when assigning to type '__m128i' from type 'int'
videoconvert.c:1301:32: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
videoconvert.c:1303:32: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
videoconvert.c:1304:32: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
videoconvert.c:1305:32: error: incompatible type for argument 1 of '_mm_or_si128'
In file included from /usr/lib64/gcc/x86_64-suse-linux/4.7/include/xmmintrin.h:1247:0,
                 from videoconvert.c:1221:
/usr/lib64/gcc/x86_64-suse-linux/4.7/include/emmintrin.h:1243:1: note: expected '__m128i' but argument is of type 'int'
videoconvert.c:1305:32: error: incompatible type for argument 2 of '_mm_or_si128'
In file included from /usr/lib64/gcc/x86_64-suse-linux/4.7/include/xmmintrin.h:1247:0,
                 from videoconvert.c:1221:
/usr/lib64/gcc/x86_64-suse-linux/4.7/include/emmintrin.h:1243:1: note: expected '__m128i' but argument is of type 'int'
videoconvert.c:1308:32: error: incompatible type for argument 2 of '_mm_add_epi16'
In file included from /usr/lib64/gcc/x86_64-suse-linux/4.7/include/xmmintrin.h:1247:0,
                 from videoconvert.c:1221:
/usr/lib64/gcc/x86_64-suse-linux/4.7/include/emmintrin.h:996:1: note: expected '__m128i' but argument is of type 'int'
videoconvert.c:1309:32: error: incompatible type for argument 2 of '_mm_add_epi16'
In file included from /usr/lib64/gcc/x86_64-suse-linux/4.7/include/xmmintrin.h:1247:0,
                 from videoconvert.c:1221:
/usr/lib64/gcc/x86_64-suse-linux/4.7/include/emmintrin.h:996:1: note: expected '__m128i' but argument is of type 'int'
videoconvert.c:1310:32: error: incompatible type for argument 2 of '_mm_add_epi16'
In file included from /usr/lib64/gcc/x86_64-suse-linux/4.7/include/xmmintrin.h:1247:0,
                 from videoconvert.c:1221:
/usr/lib64/gcc/x86_64-suse-linux/4.7/include/emmintrin.h:996:1: note: expected '__m128i' but argument is of type 'int'
videoconvert.c:1316:32: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
videoconvert.c:1317:32: error: incompatible type for argument 2 of '_mm_storel_epi64'
In file included from /usr/lib64/gcc/x86_64-suse-linux/4.7/include/xmmintrin.h:1247:0,
                 from videoconvert.c:1221:
/usr/lib64/gcc/x86_64-suse-linux/4.7/include/emmintrin.h:707:1: note: expected '__m128i' but argument is of type 'int'
videoconvert.c:1319:32: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
videoconvert.c:1320:32: error: incompatible type for argument 2 of '_mm_storel_epi64'
In file included from /usr/lib64/gcc/x86_64-suse-linux/4.7/include/xmmintrin.h:1247:0,
                 from videoconvert.c:1221:
/usr/lib64/gcc/x86_64-suse-linux/4.7/include/emmintrin.h:707:1: note: expected '__m128i' but argument is of type 'int'
videoconvert.c:1327:24: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
videoconvert.c:1335:24: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
videoconvert.c: At top level:
videoconvert.c:1348:6: warning: no previous prototype for 'Convert_BGRA_YUV420_Fallback' [-Wmissing-prototypes]
videoconvert.c: In function 'Convert_BGRA_YUV420_Fallback':
videoconvert.c:1363:24: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
videoconvert.c:1371:24: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
make[4]: *** [libgstvideoconvert_la-videoconvert.lo] Error 1
make[4]: Leaving directory `/home/zenitur/rpmbuild/BUILD/gst-plugins-base-1.2.4/gst/videoconvert'
make[3]: *** [all] Error 2
make[3]: Leaving directory `/home/zenitur/rpmbuild/BUILD/gst-plugins-base-1.2.4/gst/videoconvert'
make[2]: *** [videoconvert] Error 2
make[2]: Leaving directory `/home/zenitur/rpmbuild/BUILD/gst-plugins-base-1.2.4/gst'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/home/zenitur/rpmbuild/BUILD/gst-plugins-base-1.2.4'
make: *** [all] Error 2
ошибка: Неверный код возврата из /var/tmp/rpm-tmp.83y3cz (%build)


Ошибки сборки пакетов:
    Неверный код возврата из /var/tmp/rpm-tmp.83y3cz (%build)

Дополнено: дописал CFLAGS: -march=core2 -msse3 -mssse3, работает.

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

Покажи разницу между дефолтным и «моим» на коре2, пж.

Carb_blog4
()
5 октября 2014 г.
Ответ на: комментарий от Novell-ch

на ORC

Кто-нибудь обьяснит, зачем этот хлам нужен?

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

[code]

Performance counter stats for process id '1816':

6684.168028 task-clock (msec) # 0.222 CPUs utilized
12,919 context-switches # 0.002 M/sec
994 cpu-migrations # 0.149 K/sec
15 page-faults # 0.002 K/sec
21,026,251,117 cycles # 3.146 GHz
6,601,947,003 stalled-cycles-frontend # 31.40% frontend cycles idle
<not supported> stalled-cycles-backend
50,980,515,172 instructions # 2.42 insns per cycle
# 0.13 stalled cycles per insn
2,629,078,867 branches # 393.329 M/sec
14,069,001 branch-misses # 0.54% of all branches

30.173457857 seconds time elapsed



Performance counter stats for process id '1899':

15064.538253 task-clock (msec) # 0.548 CPUs utilized [100.00%]
13,397 context-switches # 0.889 K/sec [100.00%]
1,841 cpu-migrations # 0.122 K/sec [100.00%]
15 page-faults # 0.001 K/sec
47,656,623,006 cycles # 3.163 GHz [100.00%]
13,852,194,083 stalled-cycles-frontend # 29.07% frontend cycles idle [100.00%]
<not supported> stalled-cycles-backend
128,121,252,488 instructions # 2.69 insns per cycle
# 0.11 stalled cycles per insn [100.00%]
9,185,407,626 branches # 609.737 M/sec [100.00%]
14,321,378 branch-misses # 0.16% of all branches

27.470107935 seconds time elapsed



Performance counter stats for process id '30566':

10143.096137 task-clock (msec) # 0.353 CPUs utilized [100.00%]
14,887 context-switches # 0.001 M/sec [100.00%]
836 cpu-migrations # 0.082 K/sec [100.00%]
13 page-faults # 0.001 K/sec
32,008,426,834 cycles # 3.156 GHz [100.00%]
10,922,282,738 stalled-cycles-frontend # 34.12% frontend cycles idle [100.00%]
<not supported> stalled-cycles-backend
76,993,490,648 instructions # 2.41 insns per cycle
# 0.14 stalled cycles per insn [100.00%]
3,362,105,521 branches # 331.467 M/sec [100.00%]
14,671,094 branch-misses # 0.44% of all branches

28.771305034 seconds time elapsed

[/code]
как то так,
sse, обычный gsteamer, orc.
конечно 0.35 уже лучше чем 0.55, но до sse не дотягиваете, получается на уровне табличного 64, при том что код в разы сложнее.

Novell-ch ★★★★★
() автор топика
Ответ на: комментарий от Novell-ch

обновив orc получил
Performance counter stats for process id '31045':

13233.834604 task-clock (msec) # 0.297 CPUs utilized
25,289 context-switches # 0.002 M/sec
2,173 cpu-migrations # 0.164 K/sec
22 page-faults # 0.002 K/sec
41,150,975,897 cycles # 3.110 GHz
13,982,410,478 stalled-cycles-frontend # 33.98% frontend cycles idle
<not supported> stalled-cycles-backend
101,877,265,752 instructions # 2.48 insns per cycle
# 0.14 stalled cycles per insn
5,199,227,991 branches # 392.874 M/sec
22,454,841 branch-misses # 0.43% of all branches

44.537258699 seconds time elapsed


в общем не получилось совсем не плохо, так что в gstreamer 1.5 из коробки будет норм

Novell-ch ★★★★★
() автор топика
Ответ на: комментарий от Novell-ch

при том что код в разы сложнее.

Код — это http://cgit.freedesktop.org/gstreamer/gst-plugins-base/diff/gst-libs/gst/vide..., остальное генерируется утилитами. Значительная часть сгенерированного кода это реализация в лоб на C, на случай если liborc во время исполнения не сможет прожевать инструкции.

i-rinat ★★★★★
()
10 марта 2015 г.
Ответ на: комментарий от anonymous

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

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

все их танцы вокруг orc оказались не быстрее чем такой простой алгоритм.

Полгода не срок для разработчиков с терминальным ЧСВ?)

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

Это тот самый gstreamer, что помимо всего прочего используется всеми DE, но у которого при этом что-то около полутора разработчиков? Вряд ли можно его винить в такой ситуации в чём-то. Про кодирование его средствами я вообще слышу едва ли не впервые.

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

я так понимаю, его используют как обёртку к ffmpeg(и другим кодекам), из-за нестабильности api последнего

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

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

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

ну они пытались оптимизировать на ORC, там коммитов реально тьма, код разбух раза в 3, но результат был предсказуем.

Novell-ch ★★★★★
() автор топика
Ответ на: комментарий от devl547

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

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