SPO600 – 최종 프로젝트 - 1단계

25702 단어

안녕하세요!



우리는 여기에서 끝이 가까워지고 있으며 마침내 최종 프로젝트를 시작합니다(Open에서 작업할 예정입니다!).


1 단계



프로젝트의 첫 번째 단계에서 우리는 sve2 명령에서 이점을 얻을 수 있는 일부 패키지를 선택해야 했습니다.

이상적인 패키지는 방대한 양의 데이터를 처리하는 패키지입니다. 이렇게 하면 sve2를 최대 기능으로 사용하여 성능을 향상시킬 수 있습니다.

약간의 연구 끝에 sve2의 이점을 얻을 수 있는 두 가지 후보를 찾았습니다.
Gstreamer1FFmpeg .

Gstream1



그들에 따르면:

 GStreamer is a streaming media framework, based on graphs of filters which operate on media data. 

Applications using this library can do anything from real-time sound processing to playing videos, and just about anything else media-related.  

Its plugin-based architecture means that new data types or processing capabilities can be added simply by installing new plugins.


Gstream1은 많은 함수에 인라인 어셈블러 코드를 사용합니다here.

static inline void
inner_product_gint16_full_1_neon (gint16 * o, const gint16 * a,
    const gint16 * b, gint len, const gint16 * icoeff, gint bstride)
{
    uint32_t remainder = len % 16;
    len = len - remainder;

    asm volatile ("      vmov.s32 q0, #0\n"
                  "      cmp %[len], #0\n"
                  "      beq 2f\n"
                  "      vmov.s32 q1, #0\n"
                  "1:"
                  "      vld1.16 {d16, d17, d18, d19}, [%[b]]!\n"
                  "      vld1.16 {d20, d21, d22, d23}, [%[a]]!\n"
                  "      subs %[len], %[len], #16\n"
                  "      vmlal.s16 q0, d16, d20\n"
                  "      vmlal.s16 q1, d17, d21\n"
                  "      vmlal.s16 q0, d18, d22\n"
                  "      vmlal.s16 q1, d19, d23\n"
                  "      bne 1b\n"
                  "      vadd.s32 q0, q0, q1\n"
                  "2:"
                  "      cmp %[remainder], #0\n"
                  "      beq 4f\n"
                  "3:"
                  "      vld1.16 {d16}, [%[b]]!\n"
                  "      vld1.16 {d20}, [%[a]]!\n"
                  "      subs %[remainder], %[remainder], #4\n"
                  "      vmlal.s16 q0, d16, d20\n"
                  "      bgt 3b\n"
                  "4:"
                  "      vadd.s32 d0, d0, d1\n"
                  "      vpadd.s32 d0, d0, d0\n"
                  "      vqrshrn.s32 d0, q0, #15\n"
                  "      vst1.16 d0[0], [%[o]]\n"
                  : [a] "+r" (a), [b] "+r" (b),
                    [len] "+r" (len), [remainder] "+r" (remainder)
                  : [o] "r" (o)
                  : "cc", "q0", "q1",
                    "d16", "d17", "d18", "d19",
                    "d20", "d21", "d22", "d23");
}





FFmpeg



그들에 따르면:

FFmpeg is a complete and free Internet live audio and video broadcasting solution for Linux/Unix. It also includes a digital  VCR. It can encode in real time in many formats including MPEG1 audio and video, MPEG4, h263, ac3, asf, avi, real, mjpeg, and flash.


두 번째 옵션에는 neon를 사용하고 gcc를 사용하여 컴파일하는 많은 파일이 있습니다.




접근 방식 계획



자동 벡터화:
이 프로젝트에서 sve2를 구현하기 위한 계획은 자동 벡터화를 사용하는 것입니다. 즉, Makefile를 변경하고 컴파일러가 나를 위해 최적화를 적용하도록 하는 옵션을 포함합니다.
다음은 gstreamer1의 Makefile 예시입니다.


보시다시피 그들은 최적화를 위해 -O0을 사용하고 있으며 이는 최적화가 전혀 없음을 의미합니다.

따라서 옵션-O3 -march=armv8-a+sve2을 포함하고 테스트하여 개선되었는지 확인하겠습니다.

Makefile 정보


Makefiles는 복잡할 수 있습니다. 처음에는 이것이 쉬운 접근 방식이라고 생각했지만 프로젝트에 너무 많은 Makefiles가 있고 서로 연결되어 있습니다.
FFmpeg에서 이 예를 살펴보십시오.

MAIN_MAKEFILE=1
include ffbuild/config.mak

vpath %.c    $(SRC_PATH)
vpath %.cpp  $(SRC_PATH)
vpath %.h    $(SRC_PATH)
vpath %.inc  $(SRC_PATH)
vpath %.m    $(SRC_PATH)
vpath %.S    $(SRC_PATH)
vpath %.asm  $(SRC_PATH)
vpath %.rc   $(SRC_PATH)
vpath %.v    $(SRC_PATH)
vpath %.texi $(SRC_PATH)
vpath %.cu   $(SRC_PATH)
vpath %.ptx  $(SRC_PATH)
vpath %.metal $(SRC_PATH)
vpath %/fate_config.sh.template $(SRC_PATH)

TESTTOOLS   = audiogen videogen rotozoom tiny_psnr tiny_ssim base64 audiomatch
HOSTPROGS  := $(TESTTOOLS:%=tests/%) doc/print_options

# $(FFLIBS-yes) needs to be in linking order
FFLIBS-$(CONFIG_AVDEVICE)   += avdevice
FFLIBS-$(CONFIG_AVFILTER)   += avfilter
FFLIBS-$(CONFIG_AVFORMAT)   += avformat
FFLIBS-$(CONFIG_AVCODEC)    += avcodec
FFLIBS-$(CONFIG_POSTPROC)   += postproc
FFLIBS-$(CONFIG_SWRESAMPLE) += swresample
FFLIBS-$(CONFIG_SWSCALE)    += swscale

FFLIBS := avutil

DATA_FILES := $(wildcard $(SRC_PATH)/presets/*.ffpreset) $(SRC_PATH)/doc/ffprobe.xsd

SKIPHEADERS = compat/w32pthreads.h

# first so "all" becomes default target
all: all-yes

include $(SRC_PATH)/tools/Makefile
include $(SRC_PATH)/ffbuild/common.mak

FF_EXTRALIBS := $(FFEXTRALIBS)
FF_DEP_LIBS  := $(DEP_LIBS)
FF_STATIC_DEP_LIBS := $(STATIC_DEP_LIBS)

$(TOOLS): %$(EXESUF): %.o
        $(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(EXTRALIBS-$(*F)) $(EXTRALIBS) $(ELIBS)

target_dec_%_fuzzer$(EXESUF): target_dec_%_fuzzer.o $(FF_DEP_LIBS)
target_dec_%_fuzzer$(EXESUF): target_dec_%_fuzzer.o $(FF_DEP_LIBS)
        $(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH)

tools/target_bsf_%_fuzzer$(EXESUF): tools/target_bsf_%_fuzzer.o $(FF_DEP_LIBS)
        $(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH)

target_dem_%_fuzzer$(EXESUF): target_dem_%_fuzzer.o $(FF_DEP_LIBS)
        $(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH)

tools/target_dem_fuzzer$(EXESUF): tools/target_dem_fuzzer.o $(FF_DEP_LIBS)
        $(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH)

tools/target_io_dem_fuzzer$(EXESUF): tools/target_io_dem_fuzzer.o $(FF_DEP_LIBS)
        $(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH)

 
(it keeps going and going)


나에게는 일종의 화성 언어처럼 보입니다.


드디어



약간의 조사 후 나는 ffmpeg로 가기로 결정했습니다.
gstream1은 makeMakefiles를 사용하여 컴파일하지 않기 때문에 mesonninja를 사용하므로 이러한 기술에 대한 지식이 전혀 없기 때문에 삶이 어려워집니다.

ffmpegMakefile를 변경하려면 프로젝트를 빌드하는 Makefile에 구성을 보낼 때 ffbuild 디렉토리 내의 'config.mak' 파일을 변경해야 합니다.

지금은 그게 다야!
읽어 주셔서 감사합니다!

좋은 웹페이지 즐겨찾기