0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

自炊の画像形式をPNGからWebPに移行する3~WebPユーティリティを最強Intel C++コンパイラでビルドする

Posted at

0. はじめに

かつて業界最強とも呼ばれた Intel C++ コンパイラがいつの間にか無償で提供されるようになっていた。正しくは Intel oneAPI と呼ばれる CPU や GPU,そして FPGA までを対象に含めた統合開発環境が無償で提供されるようになったというのだ。ただしサポートは有償である。

前回の記事では,WebP ユーティリティを評判の高い Clang を用いてビルドしてみたが,今回は業界最強と呼ばれる Intel C++ コンパイラを試してみたい。

1. Intel oneAPI ツールキットの入手

Intel 公式のページ Free Intel® Software Development Tools からダウンロードできる。このうち Intel C++ コンパイラのみを使用するのであれば Intel® oneAPI Base Toolkit のみをダウンロードすればよい。ちなみに Visual Studio 2022(もしくは 2019)を事前にインストールしておいたほうが良いだろう。

なお,この記事を書いているときのバージョンは oneAPI 2024.2, Compiler Release 2024.2.1 である。

2. コマンドライン開発環境の設定

Intel oneAPI をインストールすると,スタートメニューに

  • Intel oneAPI command prompt for IA32 for Visual Studio 2022
  • Intel oneAPI command prompt for Intel 64 for Visual Studio 2022

というショートカットが作られるので,ターゲットに応じて選択する。

3. コンパイラオプション

オプションの違いをまとめると以下のようになる。※赤字は32bit版のみ有効

表1 コンパイラオプションの違い
項目 変数 Visual C++ Clang Intel C++
コンパイラ CC cl.exe clang-cl.exe icx-cl.exe
コンパイラ
オプション
CCFLAGS /O2 /GL /O2 -flto /O3 -flto
ライブラリアン LINKLIB lib.exe llvm-lib.exe llvm-lib.exe
ライブラリアン
オプション
LLFLAGS /LTCG
リンカ LINKEXE link.exe lld-link.exe lld-link.exe
リンカ
オプション
LDFLAGS /LTCG /SAFESEH /SAFESEH /SAFESEH

ちなみにリンク時最適化オプション -flto を用いなければ Visual C++ の lib.exe および link.exe を使用できる。しかし,オプション -flto を用いると専用の llvm-lib.exe および lld-link.exe を使用する必要がある。Intel onAPI ツールキットに含まれる xilib.exexilink.exe でもダメなのは,それらが単に内部で lib.exelink.exe を呼び出しているに過ぎないからだ。

llvm-lib.exe および lld-link.exe は Clang ツールのものではなく,Intel oneAPI ツールキット専用のものを使う必要があるが,名前が衝突してしまうので Intel oneAPI ツールキット専用のほうにはパスが通っていない。このため絶対パス指定で呼び出す必要がある。ちなみに llvm.exelld-link.exe が置かれているフォルダ(*)にある README.txt には下記のコメントがある。

(*) デフォルトは C:\Program Files (x86)\Intel\oneAPI\compiler\latest\bin\compiler\

These binaries are not placed in PATH during environment setup in order to reduce collisions with other toolchains.

This is a departure from OneAPI Compiler Releases before 2022.0 (December 2021), where these tools were in PATH. There may be cases where the tools which are no longer in PATH were being invoked directly in some application Makefile (or CMake configuration) and ...

Intel oneAPI の昔のリリースではパスの中に入っていたが,他のツールチェーン(おそらく Clang のこと)との衝突を防ぐためにパスから外したとのこと。しかし,必要であれば直接呼び出しても良いようだ。

4. メイクファイル

Intel C++ コンパイラ固有部を以下に示す。最適化オプションは /O3 とした。前項で述べたようにライブラリアンとリンカは絶対パス指定で呼び出す。

Makefile.intel
#-------------------------------------------------------------------------------
# Makefile for Intel C++, release build, static link
#-------------------------------------------------------------------------------
CC      = icx-cl.exe
LINKLIB = "C:\Program Files (x86)\Intel\oneAPI\compiler\latest\bin\compiler\llvm-lib.exe"
LINKEXE = "C:\Program Files (x86)\Intel\oneAPI\compiler\latest\bin\compiler\lld-link.exe"
CCFLAGS = /nologo /c /O3 /DNDEBUG /MT /I. /Isrc /W3 /EHsc
CCFLAGS = $(CCFLAGS) /DWIN32 /D_CRT_SECURE_NO_WARNINGS /DWIN32_LEAN_AND_MEAN
CCFLAGS = $(CCFLAGS) /DHAVE_WINCODEC_H /DWEBP_USE_THREAD
CCFLAGS = $(CCFLAGS) /GS- /arch:AVX2 -flto
LLFLAGS = /nologo
LDFLAGS = /nologo /LARGEADDRESSAWARE /MANIFEST:EMBED /NXCOMPAT /DYNAMICBASE
!IF "$(VS_TARGET_ARCH)" == "x86"
LDFLAGS = $(LDFLAGS) /SAFESEH
!ENDIF
WINLIBS = ole32.lib windowscodecs.lib shlwapi.lib
!IFDEF VS_TARGET_ARCH
OUT_DIR = output\release-static\$(VS_TARGET_ARCH)intel
!ELSE
!ERROR 環境変数 VS_TARGET_ARCH が未定義です。
!ENDIF
#-------------------------------------------------------------------------------
!INCLUDE Makefile.inc

共通部は長いので以下参照されたい。

Makefile.inc(共通部)はコチラ
Makefile.inc
#-------------------------------------------------------------------------------
# このファイルは下記のメイクファイルでインクルードして使用します。
# Makefile.vc2   ... x86/x64, cl.exe
# Makefile.clang ... x86/x64, clang-cl.exe
# Makefile.intel ... x86/x64, icx-cl.exe
#-------------------------------------------------------------------------------
# 出力ディレクトリ
#-------------------------------------------------------------------------------
OUTPUT_DIRS = \
	$(OUT_DIR)\lib \
	$(OUT_DIR)\bin \
	$(OUT_DIR)\obj\dec \
	$(OUT_DIR)\obj\demux \
	$(OUT_DIR)\obj\dsp \
	$(OUT_DIR)\obj\enc \
	$(OUT_DIR)\obj\examples \
	$(OUT_DIR)\obj\extras \
	$(OUT_DIR)\obj\imageio \
	$(OUT_DIR)\obj\mux \
	$(OUT_DIR)\obj\sharpyuv \
	$(OUT_DIR)\obj\utils
#-------------------------------------------------------------------------------
# ターゲットの定義
#-------------------------------------------------------------------------------
all: \
	$(OUTPUT_DIRS) \
	$(OUT_DIR)\lib\libwebpdecoder.lib \
	$(OUT_DIR)\lib\libsharpyuv.lib \
	$(OUT_DIR)\lib\libwebp.lib \
	$(OUT_DIR)\lib\libwebpdemux.lib \
	$(OUT_DIR)\lib\libwebpmux.lib \
	$(OUT_DIR)\bin\cwebp.exe \
	$(OUT_DIR)\bin\dwebp.exe \
	$(OUT_DIR)\bin\vwebp.exe \
	$(OUT_DIR)\bin\webpmux.exe \
	$(OUT_DIR)\bin\img2webp.exe \
	$(OUT_DIR)\bin\get_disto.exe \
	$(OUT_DIR)\bin\webp_quality.exe \
	$(OUT_DIR)\bin\vwebp_sdl.exe \
	$(OUT_DIR)\bin\webpinfo.exe \
	$(OUT_DIR)\bin\gif2webp.exe \
	$(OUT_DIR)\bin\anim_diff.exe \
	$(OUT_DIR)\bin\anim_dump.exe
#-------------------------------------------------------------------------------
# オブジェクトの定義
#-------------------------------------------------------------------------------
SHARPYUV_OBJS = \
	$(OUT_DIR)\obj\sharpyuv\sharpyuv.obj \
	$(OUT_DIR)\obj\sharpyuv\sharpyuv_cpu.obj \
	$(OUT_DIR)\obj\sharpyuv\sharpyuv_csp.obj \
	$(OUT_DIR)\obj\sharpyuv\sharpyuv_dsp.obj \
	$(OUT_DIR)\obj\sharpyuv\sharpyuv_gamma.obj \
	$(OUT_DIR)\obj\sharpyuv\sharpyuv_neon.obj \
	$(OUT_DIR)\obj\sharpyuv\sharpyuv_sse2.obj
DEC_OBJS = \
	$(OUT_DIR)\obj\dec\alpha_dec.obj \
	$(OUT_DIR)\obj\dec\buffer_dec.obj \
	$(OUT_DIR)\obj\dec\frame_dec.obj \
	$(OUT_DIR)\obj\dec\idec_dec.obj \
	$(OUT_DIR)\obj\dec\io_dec.obj \
	$(OUT_DIR)\obj\dec\quant_dec.obj \
	$(OUT_DIR)\obj\dec\tree_dec.obj \
	$(OUT_DIR)\obj\dec\vp8_dec.obj \
	$(OUT_DIR)\obj\dec\vp8l_dec.obj \
	$(OUT_DIR)\obj\dec\webp_dec.obj
ENC_OBJS = \
	$(OUT_DIR)\obj\enc\alpha_enc.obj \
	$(OUT_DIR)\obj\enc\analysis_enc.obj \
	$(OUT_DIR)\obj\enc\backward_references_cost_enc.obj \
	$(OUT_DIR)\obj\enc\backward_references_enc.obj \
	$(OUT_DIR)\obj\enc\config_enc.obj \
	$(OUT_DIR)\obj\enc\cost_enc.obj \
	$(OUT_DIR)\obj\enc\filter_enc.obj \
	$(OUT_DIR)\obj\enc\frame_enc.obj \
	$(OUT_DIR)\obj\enc\histogram_enc.obj \
	$(OUT_DIR)\obj\enc\iterator_enc.obj \
	$(OUT_DIR)\obj\enc\near_lossless_enc.obj \
	$(OUT_DIR)\obj\enc\picture_enc.obj \
	$(OUT_DIR)\obj\enc\picture_csp_enc.obj \
	$(OUT_DIR)\obj\enc\picture_psnr_enc.obj \
	$(OUT_DIR)\obj\enc\picture_rescale_enc.obj \
	$(OUT_DIR)\obj\enc\picture_tools_enc.obj \
	$(OUT_DIR)\obj\enc\predictor_enc.obj \
	$(OUT_DIR)\obj\enc\quant_enc.obj \
	$(OUT_DIR)\obj\enc\syntax_enc.obj \
	$(OUT_DIR)\obj\enc\token_enc.obj \
	$(OUT_DIR)\obj\enc\tree_enc.obj \
	$(OUT_DIR)\obj\enc\vp8l_enc.obj \
	$(OUT_DIR)\obj\enc\webp_enc.obj
DSP_DEC_OBJS = \
	$(OUT_DIR)\obj\dsp\alpha_processing.obj \
	$(OUT_DIR)\obj\dsp\alpha_processing_mips_dsp_r2.obj \
	$(OUT_DIR)\obj\dsp\alpha_processing_neon.obj \
	$(OUT_DIR)\obj\dsp\alpha_processing_sse2.obj \
	$(OUT_DIR)\obj\dsp\alpha_processing_sse41.obj \
	$(OUT_DIR)\obj\dsp\cpu.obj $(OUT_DIR)\obj\dsp\dec.obj \
	$(OUT_DIR)\obj\dsp\dec_clip_tables.obj \
	$(OUT_DIR)\obj\dsp\dec_mips32.obj \
	$(OUT_DIR)\obj\dsp\dec_mips_dsp_r2.obj \
	$(OUT_DIR)\obj\dsp\dec_msa.obj \
	$(OUT_DIR)\obj\dsp\dec_neon.obj \
	$(OUT_DIR)\obj\dsp\dec_sse2.obj \
	$(OUT_DIR)\obj\dsp\dec_sse41.obj \
	$(OUT_DIR)\obj\dsp\filters.obj \
	$(OUT_DIR)\obj\dsp\filters_mips_dsp_r2.obj \
	$(OUT_DIR)\obj\dsp\filters_msa.obj \
	$(OUT_DIR)\obj\dsp\filters_neon.obj \
	$(OUT_DIR)\obj\dsp\filters_sse2.obj \
	$(OUT_DIR)\obj\dsp\lossless.obj \
	$(OUT_DIR)\obj\dsp\lossless_mips_dsp_r2.obj \
	$(OUT_DIR)\obj\dsp\lossless_msa.obj \
	$(OUT_DIR)\obj\dsp\lossless_neon.obj \
	$(OUT_DIR)\obj\dsp\lossless_sse2.obj \
	$(OUT_DIR)\obj\dsp\lossless_sse41.obj \
	$(OUT_DIR)\obj\dsp\rescaler.obj \
	$(OUT_DIR)\obj\dsp\rescaler_mips32.obj \
	$(OUT_DIR)\obj\dsp\rescaler_mips_dsp_r2.obj \
	$(OUT_DIR)\obj\dsp\rescaler_msa.obj \
	$(OUT_DIR)\obj\dsp\rescaler_neon.obj \
	$(OUT_DIR)\obj\dsp\rescaler_sse2.obj \
	$(OUT_DIR)\obj\dsp\upsampling.obj \
	$(OUT_DIR)\obj\dsp\upsampling_mips_dsp_r2.obj \
	$(OUT_DIR)\obj\dsp\upsampling_msa.obj \
	$(OUT_DIR)\obj\dsp\upsampling_neon.obj \
	$(OUT_DIR)\obj\dsp\upsampling_sse2.obj \
	$(OUT_DIR)\obj\dsp\upsampling_sse41.obj \
	$(OUT_DIR)\obj\dsp\yuv.obj \
	$(OUT_DIR)\obj\dsp\yuv_mips32.obj \
	$(OUT_DIR)\obj\dsp\yuv_mips_dsp_r2.obj \
	$(OUT_DIR)\obj\dsp\yuv_neon.obj \
	$(OUT_DIR)\obj\dsp\yuv_sse2.obj \
	$(OUT_DIR)\obj\dsp\yuv_sse41.obj
DSP_ENC_OBJS = \
	$(OUT_DIR)\obj\dsp\cost.obj \
	$(OUT_DIR)\obj\dsp\cost_mips32.obj \
	$(OUT_DIR)\obj\dsp\cost_mips_dsp_r2.obj \
	$(OUT_DIR)\obj\dsp\cost_neon.obj \
	$(OUT_DIR)\obj\dsp\cost_sse2.obj \
	$(OUT_DIR)\obj\dsp\enc.obj \
	$(OUT_DIR)\obj\dsp\enc_mips32.obj \
	$(OUT_DIR)\obj\dsp\enc_mips_dsp_r2.obj \
	$(OUT_DIR)\obj\dsp\enc_msa.obj \
	$(OUT_DIR)\obj\dsp\enc_neon.obj \
	$(OUT_DIR)\obj\dsp\enc_sse2.obj \
	$(OUT_DIR)\obj\dsp\enc_sse41.obj \
	$(OUT_DIR)\obj\dsp\lossless_enc.obj \
	$(OUT_DIR)\obj\dsp\lossless_enc_mips32.obj \
	$(OUT_DIR)\obj\dsp\lossless_enc_mips_dsp_r2.obj \
	$(OUT_DIR)\obj\dsp\lossless_enc_msa.obj \
	$(OUT_DIR)\obj\dsp\lossless_enc_neon.obj \
	$(OUT_DIR)\obj\dsp\lossless_enc_sse2.obj \
	$(OUT_DIR)\obj\dsp\lossless_enc_sse41.obj \
	$(OUT_DIR)\obj\dsp\ssim.obj \
	$(OUT_DIR)\obj\dsp\ssim_sse2.obj
UTILS_DEC_OBJS = \
	$(OUT_DIR)\obj\utils\bit_reader_utils.obj \
	$(OUT_DIR)\obj\utils\color_cache_utils.obj \
	$(OUT_DIR)\obj\utils\filters_utils.obj \
	$(OUT_DIR)\obj\utils\huffman_utils.obj \
	$(OUT_DIR)\obj\utils\palette.obj \
	$(OUT_DIR)\obj\utils\quant_levels_dec_utils.obj \
	$(OUT_DIR)\obj\utils\rescaler_utils.obj \
	$(OUT_DIR)\obj\utils\random_utils.obj \
	$(OUT_DIR)\obj\utils\thread_utils.obj \
	$(OUT_DIR)\obj\utils\utils.obj
UTILS_ENC_OBJS = \
	$(OUT_DIR)\obj\utils\bit_writer_utils.obj \
	$(OUT_DIR)\obj\utils\huffman_encode_utils.obj \
	$(OUT_DIR)\obj\utils\quant_levels_utils.obj
IMAGEIO_DEC_OBJS = \
	$(OUT_DIR)\obj\imageio\image_dec.obj \
	$(OUT_DIR)\obj\imageio\jpegdec.obj \
	$(OUT_DIR)\obj\imageio\metadata.obj \
	$(OUT_DIR)\obj\imageio\pngdec.obj \
	$(OUT_DIR)\obj\imageio\pnmdec.obj \
	$(OUT_DIR)\obj\imageio\tiffdec.obj \
	$(OUT_DIR)\obj\imageio\webpdec.obj \
	$(OUT_DIR)\obj\imageio\wicdec.obj
IMAGEIO_ENC_OBJS = \
	$(OUT_DIR)\obj\imageio\image_enc.obj
IMAGEIO_UTIL_OBJS = \
	$(OUT_DIR)\obj\imageio\imageio_util.obj
MUX_OBJS = \
	$(OUT_DIR)\obj\mux\anim_encode.obj \
	$(OUT_DIR)\obj\mux\muxedit.obj \
	$(OUT_DIR)\obj\mux\muxinternal.obj \
	$(OUT_DIR)\obj\mux\muxread.obj
DEMUX_OBJS = \
	$(OUT_DIR)\obj\demux\anim_decode.obj \
	$(OUT_DIR)\obj\demux\demux.obj
EXTRAS_OBJS = \
	$(OUT_DIR)\obj\extras\extras.obj \
	$(OUT_DIR)\obj\extras\quality_estimate.obj \
	$(OUT_DIR)\obj\extras\sharpyuv_risk_table.obj
EX_UTIL_OBJS = \
	$(OUT_DIR)\obj\examples\example_util.obj
EX_GIF_DEC_OBJS = \
	$(OUT_DIR)\obj\examples\gifdec.obj
EX_ANIM_UTIL_OBJS = \
	$(OUT_DIR)\obj\examples\anim_util.obj
#-------------------------------------------------------------------------------
# スタティックリンクライブラリ *.LIB の依存関係の定義
#-------------------------------------------------------------------------------
$(OUT_DIR)\lib\libsharpyuv.lib: $(SHARPYUV_OBJS)
$(OUT_DIR)\lib\libwebpmux.lib: $(MUX_OBJS)
$(OUT_DIR)\lib\libwebpdemux.lib: $(DEMUX_OBJS)
$(OUT_DIR)\lib\libwebpdecoder.lib: \
	$(DEC_OBJS) $(DSP_DEC_OBJS) $(UTILS_DEC_OBJS)
$(OUT_DIR)\lib\libwebp.lib: \
	$(DEC_OBJS) $(DSP_DEC_OBJS) $(UTILS_ENC_OBJS) \
	$(ENC_OBJS) $(DSP_ENC_OBJS) $(UTILS_DEC_OBJS) \
	$(OUT_DIR)\lib\libsharpyuv.lib
#-------------------------------------------------------------------------------
# 実行ファイル *.EXE の依存関係の定義
#-------------------------------------------------------------------------------
$(OUT_DIR)\bin\cwebp.exe: $(OUT_DIR)\obj\examples\cwebp.obj \
	$(EX_UTIL_OBJS) \
	$(IMAGEIO_DEC_OBJS) $(IMAGEIO_UTIL_OBJS) \
	$(OUT_DIR)\lib\libwebpdemux.lib \
	$(OUT_DIR)\lib\libsharpyuv.lib \
	$(OUT_DIR)\lib\libwebp.lib
$(OUT_DIR)\bin\dwebp.exe: $(OUT_DIR)\obj\examples\dwebp.obj \
	$(EX_UTIL_OBJS) \
	$(IMAGEIO_DEC_OBJS) $(IMAGEIO_ENC_OBJS) $(IMAGEIO_UTIL_OBJS) \
	$(OUT_DIR)\lib\libwebpdemux.lib \
	$(OUT_DIR)\lib\libwebp.lib
$(OUT_DIR)\bin\vwebp.exe: $(OUT_DIR)\obj\examples\vwebp.obj \
	$(EX_UTIL_OBJS) \
	$(IMAGEIO_UTIL_OBJS) \
	$(OUT_DIR)\lib\libwebpdemux.lib \
	$(OUT_DIR)\lib\libwebp.lib
$(OUT_DIR)\bin\webpmux.exe: $(OUT_DIR)\obj\examples\webpmux.obj \
	$(EX_UTIL_OBJS) \
	$(IMAGEIO_UTIL_OBJS) \
	$(OUT_DIR)\lib\libwebpmux.lib \
	$(OUT_DIR)\lib\libwebp.lib
$(OUT_DIR)\bin\img2webp.exe: $(OUT_DIR)\obj\examples\img2webp.obj \
	$(EX_UTIL_OBJS) \
	$(IMAGEIO_DEC_OBJS) $(IMAGEIO_UTIL_OBJS) \
	$(OUT_DIR)\lib\libsharpyuv.lib \
	$(OUT_DIR)\lib\libwebp.lib \
	$(OUT_DIR)\lib\libwebpdemux.lib \
	$(OUT_DIR)\lib\libwebpmux.lib
$(OUT_DIR)\bin\get_disto.exe: $(OUT_DIR)\obj\extras\get_disto.obj \
	$(IMAGEIO_DEC_OBJS) $(IMAGEIO_UTIL_OBJS) \
	$(OUT_DIR)\lib\libwebpdemux.lib \
	$(OUT_DIR)\lib\libwebp.lib
$(OUT_DIR)\bin\webp_quality.exe: $(OUT_DIR)\obj\extras\webp_quality.obj \
	$(EXTRAS_OBJS) \
	$(IMAGEIO_UTIL_OBJS) \
	$(OUT_DIR)\lib\libwebp.lib
$(OUT_DIR)\bin\vwebp_sdl.exe: $(OUT_DIR)\obj\extras\vwebp_sdl.obj \
	$(OUT_DIR)\obj\extras\webp_to_sdl.obj \
	$(IMAGEIO_UTIL_OBJS) \
	$(OUT_DIR)\lib\libwebp.lib
$(OUT_DIR)\bin\webpinfo.exe: $(OUT_DIR)\obj\examples\webpinfo.obj \
	$(EX_UTIL_OBJS) \
	$(IMAGEIO_DEC_OBJS) $(IMAGEIO_UTIL_OBJS) \
	$(OUT_DIR)\lib\libwebpdemux.lib \
	$(OUT_DIR)\lib\libwebp.lib
$(OUT_DIR)\bin\gif2webp.exe: $(OUT_DIR)\obj\examples\gif2webp.obj \
	$(EX_UTIL_OBJS) $(EX_GIF_DEC_OBJS) \
	$(IMAGEIO_UTIL_OBJS) \
	$(OUT_DIR)\lib\libwebpmux.lib \
	$(OUT_DIR)\lib\libwebp.lib
$(OUT_DIR)\bin\anim_diff.exe: $(OUT_DIR)\obj\examples\anim_diff.obj \
	$(EX_UTIL_OBJS) $(EX_GIF_DEC_OBJS) $(EX_ANIM_UTIL_OBJS) \
	$(IMAGEIO_UTIL_OBJS) \
	$(OUT_DIR)\lib\libwebpdemux.lib \
	$(OUT_DIR)\lib\libwebp.lib
$(OUT_DIR)\bin\anim_dump.exe: $(OUT_DIR)\obj\examples\anim_dump.obj \
	$(EX_UTIL_OBJS) $(EX_GIF_DEC_OBJS) $(EX_ANIM_UTIL_OBJS) \
	$(IMAGEIO_ENC_OBJS) $(IMAGEIO_UTIL_OBJS) \
	$(OUT_DIR)\lib\libwebpdemux.lib \
	$(OUT_DIR)\lib\libwebp.lib
#-------------------------------------------------------------------------------
# 出力ディレクトリの生成
#-------------------------------------------------------------------------------
$(OUTPUT_DIRS):
	@if not exist $@ mkdir $@
#-------------------------------------------------------------------------------
# ライブラリ *.LIB の生成コマンド
#-------------------------------------------------------------------------------
$(OUT_DIR)\lib\libwebpdecoder.lib \
$(OUT_DIR)\lib\libsharpyuv.lib \
$(OUT_DIR)\lib\libwebp.lib \
$(OUT_DIR)\lib\libwebpdemux.lib \
$(OUT_DIR)\lib\libwebpmux.lib:
	$(LINKLIB) $(LLFLAGS) /out:$@ $**
#-------------------------------------------------------------------------------
# 実行ファイル *.EXE の生成コマンド
#-------------------------------------------------------------------------------
$(OUT_DIR)\bin\cwebp.exe \
$(OUT_DIR)\bin\dwebp.exe \
$(OUT_DIR)\bin\vwebp.exe \
$(OUT_DIR)\bin\webpmux.exe \
$(OUT_DIR)\bin\img2webp.exe \
$(OUT_DIR)\bin\get_disto.exe \
$(OUT_DIR)\bin\webp_quality.exe \
$(OUT_DIR)\bin\vwebp_sdl.exe \
$(OUT_DIR)\bin\webpinfo.exe \
$(OUT_DIR)\bin\gif2webp.exe \
$(OUT_DIR)\bin\anim_diff.exe \
$(OUT_DIR)\bin\anim_dump.exe:
	$(LINKEXE) $(LDFLAGS) /out:$@ $** $(WINLIBS)
#-------------------------------------------------------------------------------
# オブジェクト *.OBJ の生成コマンド
#-------------------------------------------------------------------------------
{examples}.c{$(OUT_DIR)\obj\examples}.obj::
	$(CC) $(CCFLAGS) /Fo$(OUT_DIR)\obj\examples\ $<
{extras}.c{$(OUT_DIR)\obj\extras}.obj::
	$(CC) $(CCFLAGS) /Fo$(OUT_DIR)\obj\extras\ $<
{imageio}.c{$(OUT_DIR)\obj\imageio}.obj::
	$(CC) $(CCFLAGS) /Fo$(OUT_DIR)\obj\imageio\ $<
{sharpyuv}.c{$(OUT_DIR)\obj\sharpyuv}.obj::
	$(CC) $(CCFLAGS) /Fo$(OUT_DIR)\obj\sharpyuv\ $<
{src\dec}.c{$(OUT_DIR)\obj\dec}.obj::
	$(CC) $(CCFLAGS) /Fo$(OUT_DIR)\obj\dec\ $<
{src\dsp}.c{$(OUT_DIR)\obj\dsp}.obj::
	$(CC) $(CCFLAGS) /Fo$(OUT_DIR)\obj\dsp\ $<
{src\enc}.c{$(OUT_DIR)\obj\enc}.obj::
	$(CC) $(CCFLAGS) /Fo$(OUT_DIR)\obj\enc\ $<
{src\mux}.c{$(OUT_DIR)\obj\mux}.obj::
	$(CC) $(CCFLAGS) /Fo$(OUT_DIR)\obj\mux\ $<
{src\demux}.c{$(OUT_DIR)\obj\demux}.obj::
	$(CC) $(CCFLAGS) /Fo$(OUT_DIR)\obj\demux\ $<
{src\utils}.c{$(OUT_DIR)\obj\utils}.obj::
	$(CC) $(CCFLAGS) /Fo$(OUT_DIR)\obj\utils\ $<
#-------------------------------------------------------------------------------
# 生成物のクリーンナップ
#-------------------------------------------------------------------------------
clean:
	@if exist $(OUT_DIR) rd /s /q $(OUT_DIR)

メイクファイルの実行は 32bit or 64bit いずれかの開発環境で下記のコマンドを実行するだけだ。

ビルド手順
nmake -f Makefile.intel

生成物は下記のフォルダに作られる。

表2 生成物のフォルダ
コンバイラ ターゲット フォルダ
Visual C++ 32bit output\release-static\x86vc\bin
64bit output\release-static\x64vc\bin
Clang 32bit output\release-static\x86clang\bin
64bit output\release-static\x64clang\bin
Intel C++ 32bit output\release-static\x86intel\bin
64bit output\release-static\x64intel\bin

5. バイナリサイズの比較

original とはWebP のダウンロードリポジトリからダウンロードしたものである。

表3 バイナリサイズの比較
コンパイラ 32bit版 64bit版
original なし 742,912 bytes
Visual C++ 609,280 bytes 749,056 bytes
Clang 817,152 bytes 866,816 bytes
Intel C++ 814,592 bytes 866,816 bytes

6. パフォーマンス比較

題材は前々回の記事で用いたサンプル画像である。300dpiでスキャンしたカラー画像4枚,白黒画像36枚のビットマップファイル *.BMP を cwebp.exe を用いて可逆圧縮(lossless)モードかつ最高品質 z=9 にて圧縮した際に要した計算時間の平均値を示す。original を基準100とした相対値で示す。

なお,今回もインテル第8,11,13世代のプロセッサで比較した。

ちなみに第8世代を 100 とすると,第11世代は 70~75,第13世代は 50~55 となる。

7. まとめ

  • やはり Intel C++ コンパイラは最強である。

  • ただし,プロセッサの世代が新しくなるにつれて Intel C++ コンパイラの優位性が徐々に小さくなっていくのが悲しいところである。

  • 最大の課題は Intel C++ コンパイラは機能・オプションが多過ぎて*正直*使いこなすのが難しいことだろうか。

8. 参考文献

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?