Козлов Василий Сергеевич P3215 Лаб 5
Для запуска бенчмарка необходимо запустить программу ./imtr-bench, установив следующие переменные окружения: LARGE_IMAGE_PATH, SMALL_IMAGE_PATH .
Для запуска нужно запустить из корневой папки проекта скрипт build_and_test.sh
Результаты работы бенчмарка на сервере с процессором: Intel(R) Xeon(R) Gold 6154 CPU @ 3.00GHz
clang-18 -O2
--------------------------------------------------------------
Benchmark                    Time             CPU   Iterations
--------------------------------------------------------------
CSepiaSmallImage         0.166 us        0.162 us      4130002
CSepiaLargeImage          4978 us         4947 us          133
SimdSepiaSmallImage      0.290 us        0.289 us      2396126
SimdSepiaLargeImage       9315 us         9278 us           74
gcc-13 -O2
--------------------------------------------------------------
Benchmark                    Time             CPU   Iterations
--------------------------------------------------------------
CSepiaSmallImage         0.124 us        0.123 us      5681197
CSepiaLargeImage          3560 us         3545 us          183
SimdSepiaSmallImage      0.128 us        0.128 us      5480104
SimdSepiaLargeImage       4085 us         4069 us          172
Результаты работы бенчмарка на компьютере с процессором: AMD Ryzen 7 5700X 8-Core Processor 4.40GHz
clang-18 -O2
--------------------------------------------------------------
Benchmark                    Time             CPU   Iterations
--------------------------------------------------------------
CSepiaSmallImage         0.072 us        0.072 us      9814096
CSepiaLargeImage          2189 us         2180 us          319
SimdSepiaSmallImage      0.129 us        0.129 us      5255665
SimdSepiaLargeImage       4092 us         4076 us          172
clang-18 -Ofast -msse4 -mavx -mavx2
--------------------------------------------------------------
Benchmark                    Time             CPU   Iterations
--------------------------------------------------------------
CSepiaSmallImage         0.072 us        0.072 us      9704557
CSepiaLargeImage          2090 us         2068 us          318
SimdSepiaSmallImage      0.130 us        0.129 us      5446386
SimdSepiaLargeImage       4109 us         4093 us          171
gcc-14 -O2
--------------------------------------------------------------
Benchmark                    Time             CPU   Iterations
--------------------------------------------------------------
CSepiaSmallImage         0.123 us        0.122 us      5798950
CSepiaLargeImage          3816 us         3799 us          184
SimdSepiaSmallImage      0.146 us        0.145 us      4771974
SimdSepiaLargeImage       4381 us         4362 us          152
gcc-14 -Ofast -msse4 -mavx -mavx2
--------------------------------------------------------------
Benchmark                    Time             CPU   Iterations
--------------------------------------------------------------
CSepiaSmallImage         0.120 us        0.120 us      5854546
CSepiaLargeImage          3616 us         3601 us          184
SimdSepiaSmallImage      0.129 us        0.128 us      5455156
SimdSepiaLargeImage       4115 us         4098 us          171
Код, сгенерированный компилятором clang-18 -O3 (код привожу, чтобы показать, как компилятор хорошо справляется с использованием векторных инструкций, думаю, что у большинства программистов не получится сделать это лучше)
.LBB31_9:
	movzwl	(%rdx,%rsi), %edi
	movzbl	%dil, %r8d
	xorps	%xmm12, %xmm12
	cvtsi2ss	%r8d, %xmm12
	shrl	$8, %edi
	xorps	%xmm13, %xmm13
	cvtsi2ss	%edi, %xmm13
	movzbl	2(%rdx,%rsi), %edi
	xorps	%xmm10, %xmm10
	cvtsi2ss	%edi, %xmm10
	movaps	%xmm12, %xmm11
	mulss	%xmm0, %xmm11
	movaps	%xmm13, %xmm14
	mulss	%xmm1, %xmm14
	addss	%xmm11, %xmm14
	movaps	%xmm10, %xmm11
	mulss	%xmm2, %xmm11
	addss	%xmm14, %xmm11
	movaps	%xmm12, %xmm14
	mulss	%xmm3, %xmm14
	movaps	%xmm13, %xmm15
	mulss	%xmm4, %xmm15
	addss	%xmm14, %xmm15
	movaps	%xmm10, %xmm14
	mulss	%xmm5, %xmm14
	addss	%xmm15, %xmm14
	mulss	%xmm6, %xmm12
	mulss	%xmm7, %xmm13
	addss	%xmm12, %xmm13
	mulss	%xmm8, %xmm10
	addss	%xmm13, %xmm10
	minss	%xmm9, %xmm14
	minss	%xmm9, %xmm10
	cvttss2si	%xmm10, %edi
	cvttss2si	%xmm14, %r8d
	minss	%xmm9, %xmm11
	cvttss2si	%xmm11, %r9d
	movb	%dil, (%rcx,%rsi)
	movb	%r8b, 1(%rcx,%rsi)
	movb	%r9b, 2(%rcx,%rsi)
	addq	$3, %rsi
	decl	%r15d
	jne	.LBB31_9
Код, сгенерированный компилятором clang-18 -O3 -mavx2
	movzwl	(%r14,%r8), %r11d
	movzbl	2(%r14,%r8), %r10d
	shll	$16, %r10d
	orl	%r11d, %r10d
	movzwl	3(%r14,%r8), %ebp
	movzbl	5(%r14,%r8), %r11d
	shll	$16, %r11d
	orl	%ebp, %r11d
	movzwl	6(%r14,%r8), %r12d
	movzbl	8(%r14,%r8), %ebp
	shll	$16, %ebp
	orl	%r12d, %ebp
	movzwl	9(%r14,%r8), %r13d
	movzbl	11(%r14,%r8), %r12d
	shll	$16, %r12d
	orl	%r13d, %r12d
	movzwl	12(%r14,%r8), %r13d
	movzbl	14(%r14,%r8), %edi
	shll	$16, %edi
	orl	%r13d, %edi
	movzwl	15(%r14,%r8), %r13d
	movzbl	17(%r14,%r8), %esi
	shll	$16, %esi
	orl	%r13d, %esi
	movzwl	18(%r14,%r8), %r13d
	movzbl	20(%r14,%r8), %ebx
	shll	$16, %ebx
	orl	%r13d, %ebx
	movzwl	21(%r14,%r8), %r13d
	movzbl	23(%r14,%r8), %edx
	shll	$16, %edx
	vmovd	%edi, %xmm11
	vpinsrd	$1, %esi, %xmm11, %xmm11
	vpinsrd	$2, %ebx, %xmm11, %xmm11
	orl	%r13d, %edx
	vpinsrd	$3, %edx, %xmm11, %xmm11
	vmovd	%r10d, %xmm13
	vpinsrd	$1, %r11d, %xmm13, %xmm13
	vpinsrd	$2, %ebp, %xmm13, %xmm13
	vpinsrd	$3, %r12d, %xmm13, %xmm13
	vinserti128	$1, %xmm11, %ymm13, %ymm11
	vpand	32(%rsp), %ymm11, %ymm13
	vcvtdq2ps	%ymm13, %ymm13
	vpshufb	.LCPI31_1(%rip), %ymm11, %ymm14
	vcvtdq2ps	%ymm14, %ymm14
	vpshufb	.LCPI31_2(%rip), %ymm11, %ymm11
	vcvtdq2ps	%ymm11, %ymm11
	vmulps	%ymm2, %ymm13, %ymm15
	vmulps	%ymm3, %ymm14, %ymm1
	vaddps	%ymm1, %ymm15, %ymm1
	vmulps	%ymm4, %ymm11, %ymm15
	vaddps	%ymm1, %ymm15, %ymm1
	vmulps	%ymm5, %ymm13, %ymm15
	vmulps	%ymm6, %ymm14, %ymm0
	vaddps	%ymm0, %ymm15, %ymm0
	vmulps	%ymm7, %ymm11, %ymm15
	vaddps	%ymm0, %ymm15, %ymm0
	vmulps	%ymm8, %ymm13, %ymm13
	vmulps	%ymm9, %ymm14, %ymm14
	vaddps	%ymm14, %ymm13, %ymm13
	vmulps	%ymm10, %ymm11, %ymm11
	vaddps	%ymm13, %ymm11, %ymm11
	vminps	%ymm12, %ymm1, %ymm1
	vminps	%ymm12, %ymm0, %ymm0
	vminps	%ymm12, %ymm11, %ymm11
	vcvttps2dq	%ymm11, %ymm11
	vextracti128	$1, %ymm11, %xmm13
	vpackssdw	%xmm13, %xmm11, %xmm11
	vcvttps2dq	%ymm0, %ymm0
	vextracti128	$1, %ymm0, %xmm13
	vpackssdw	%xmm13, %xmm0, %xmm0
	vpackuswb	%xmm0, %xmm11, %xmm0
	vcvttps2dq	%ymm1, %ymm1
	vextracti128	$1, %ymm1, %xmm11
	vpackssdw	%xmm11, %xmm1, %xmm1
	vpackuswb	%xmm1, %xmm1, %xmm1
	vpshufb	.LCPI31_13(%rip), %xmm0, %xmm11
	vpshufb	.LCPI31_14(%rip), %xmm1, %xmm13
	vpor	%xmm13, %xmm11, %xmm11
	vpshufb	.LCPI31_15(%rip), %xmm0, %xmm0
	vpshufb	.LCPI31_16(%rip), %xmm1, %xmm1
	vpor	%xmm1, %xmm0, %xmm0
	vmovq	%xmm0, 16(%rax,%r8)
	vmovdqu	%xmm11, (%rax,%r8)
	addq	$24, %r8
	addq	$-8, %r9
	jne	.LBB31_6
	movq	8(%rsp), %rsi
	cmpq	(%rsp), %rsi
	movq	24(%rsp), %rbx
	movq	16(%rsp), %r14
	je	.LBB31_10
Код, сгенерированный компилятором gcc-14 -O3
	movzbl	(%rax), %edx
	pxor	%xmm0, %xmm0
	pxor	%xmm14, %xmm14
	addq	$3, %rax
	pxor	%xmm13, %xmm13
	addq	$3, %rcx
	cvtsi2ssl	%edx, %xmm0
	movzbl	-2(%rax), %edx
	cvtsi2ssl	%edx, %xmm14
	movzbl	-1(%rax), %edx
	movaps	%xmm0, %xmm2
	cvtsi2ssl	%edx, %xmm13
	mulss	%xmm12, %xmm2
	movaps	%xmm14, %xmm3
	movaps	%xmm14, %xmm15
	mulss	%xmm11, %xmm3
	mulss	%xmm8, %xmm15
	mulss	%xmm5, %xmm14
	addss	%xmm3, %xmm2
	movaps	%xmm13, %xmm3
	mulss	%xmm10, %xmm3
	addss	%xmm3, %xmm2
	movaps	%xmm0, %xmm3
	mulss	%xmm9, %xmm3
	mulss	%xmm6, %xmm0
	minss	%xmm1, %xmm2
	addss	%xmm15, %xmm3
	movaps	%xmm13, %xmm15
	mulss	%xmm4, %xmm13
	addss	%xmm14, %xmm0
	mulss	%xmm7, %xmm15
	addss	%xmm13, %xmm0
	addss	%xmm15, %xmm3
	minss	%xmm1, %xmm0
	cvttss2sil	%xmm0, %edx
	movaps	%xmm3, %xmm0
	minss	%xmm1, %xmm0
	movb	%dl, -3(%rcx)
	cvttss2sil	%xmm0, %edx
	movb	%dl, -2(%rcx)
	cvttss2sil	%xmm2, %edx
	movb	%dl, -1(%rcx)
	cmpq	%rsi, %rax
	jne	.L9
Код gcc-14 -O3 -mavx2 намного больше.
Бонус:
Apple M1
clang-17 -O3
--------------------------------------------------------------
Benchmark                    Time             CPU   Iterations
--------------------------------------------------------------
CSepiaSmallImage         0.217 us        0.217 us      3189386
CSepiaLargeImage          7080 us         7037 us           99
Вывод: используйте clang крайне сложно сделать код лучше компилятора, если у компилятора есть информация о вызываемых функциях и выставлены правильные флаги оптимизации.
P.S. Если добавить округление дробных значений, перед конвертацией их в целые числа, то получается следюущий результат:
--------------------------------------------------------------
Benchmark                    Time             CPU   Iterations
--------------------------------------------------------------
CSepiaSmallImage         0.336 us        0.335 us      2064737
CSepiaLargeImage         11496 us        11441 us           61
SimdSepiaSmallImage      0.146 us        0.146 us      4811108
SimdSepiaLargeImage       4651 us         4628 us          151