Козлов Василий Сергеевич 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