<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=http://email.email.llvm.org/c/eJztWttznLYa_2vwC8MOunB78IM3duZk2rSnzjkzffMIELskLGxA2E7_-kriskiIDXbcumnL2MB--iT9vqs-aTeu0i-XObMTUtoxtWt6rKu0TahdlUVe8kdtF1VCCttyry33qrvvGTs2Frqy4Fv-9_DwsPnc5sknJ6Zlst8k1YFTP_N_xh5uyI__Rbv0y6_ezY83t2F0nXi3vwS_3kyHs3y3-0uOx54CUUozMf_tDZ8i_J8FI3tyJVXZMJtT_ek4DavbhNnvCavzR2xbwbajix5ZURFm04IeaMkay9sC3_KuBQ-w4BvbNdye0xBcW6ifdfqed8ockOXlPa0Zl6uTricLGQ-EyaeCfehWtWwcUdA79dsxaWjK7WULsyhWoW1S5CklZXMkCe0Nw6fYN_xJih2Na9JR-Pj8JWvLhOVct_xdYmyooFZtfS0pKX3c7NnhhKCzQ6fbEgDbQtdShM1E0S7Xs1BOCc3tYGhH5nY4tGNzOxraATS24679BHp6ldDcyRtBmdv9EZS5PRhBIWN7OCrF3B6dBY3MncCoarzAMOoaYDPDqGy4wDBqGy0wnFc3XujlnevFes-SyoJX3dziyZXvdFAlFY1UC24ndNjTkeSG2hgdFWm8uB8DamPjMyg7V5C61fA4nSPMsYM5RjkvmKPs6HOczoR7DUrUo-x5oREP1HQ50hVdDvNCRZfjyJouR-41KLGqy4l9nDl2pGKfamM7R4k0XU48wpmjRFjJudOMl1LWowSSV_qp9Jrhc689NHzuZ8bDZ3XsPOPksB9VDOzOloJJ2uerweYDFauIaSl6_i1SMImrpqyty_nywxe4Jb28K--laoSgbwVB6SmgayuE5Ga9IrsBznUBQxcu_jwBACWksUIdeIEaWL3JZgE3jjLwSycZuSeuHK2EDhXoepyrIOFIVTPaAAYqYNSsCGfAVUHh06EjBbqeioAyrdkWJ-AqGD116-CRIuiYhNZDxycfgyu7eFNpZ-kbKOn7JK2SLlX8YO5j04VBMxT4Bh_zFehzb3IMK4wqkGaoGfSBPveyqaDP8LFAgW70ptkiOGh97mWOQY9QEV_LAzPoT_Cx8ORjaGWXyGQoaJQWGg0FF_BDLY-NoxgNBZ_hY8A1WWoBpW4pHb1iKa0kgTPkqqTPcDIATLENjQGyYI2FAJkVTjp6JRPAZ3gZgCc3w2v7IKO8p2A3lH5owVYImWyFkEk7SLfVqahaLy82xghUsOslnjFGkG4rrNHhDL3BVk_C7hljBCko9TJUy2YT9IaIRcYYQXo2GPPoGeyGMm8s8YYDFsLyxL6v8tTevr_rzyXu3g3HGfL850DqT-IUAl194OzUgr7ddC8LxxpiM3glmgJRgSJx88UtEjc40uSbN56_ROPHcGQJRj44PX0Rk2VVLWxAWlbZd9wiVwugxNUD4lYbD2okyVQby4b5ccdW_Om8mnquq58q9vOR5Yf8N7o0x8kCw8v25qc3_3l_dfsD72Iwwqn7CpvBv5nRVhriKQb-E4wGFasNh6FTI7I9tdM8y2jN0VCOiT1QWtrsobIT0lA7b5Tz2fmB6jqR1-hwOKCVe1BSplPqOiOsgWLUggX5sr3ND2RH5bCheg7dNrR2ZGuz2eVs38aCwjemjIPpDz8BDCH2gS9eccTfIAgd3_cwjePMQdBLHJyRyIm8iDie78ZhGpPQp-7mWO4EwAmcuGW2MMyR1txRD0RYRhhJWGPf7qjNMzj3E45ms_mjxfBw4EA_cL3MTx1AEuJg6hKHJCh0vNhzfZoCP8wCgxi9g84zSdDYpDkY_Wqk90FybJu9PJnw6vi41MIXw6UWvNgCF-d5VFqaNpaRB7H7KA9EBE-jYjlU93bfO817Fm1qztIeG9txH-MMpNw2gic_CpVJ_sfDwR0yg8XXYOj6IEq4M7_R8oRIW2VVfjlUbWOXhHuBOIKXLi6aP23z3Yd3_y9zHiVw6z5GEFvoRodCOJR-Uj69-4jcHlFzHI1oAI6idcDDlwAO1gCH64B73jrgwUsAd9cAB-uAB2AdcP8FgIfZ14GfAy0eXDDS84hI6BHHx2KB2Z0z6wGYkKL4bNsQIDd0DVJ2dcXwWrMfKD3etmWZi4QUSmlVoRhtWBetApcR4MeSigfkWRwTMecTilIpCFcnIcsTCxmNwn6U8770xAUlnb6x6nV9pvKWkpngemPIlhMW4PUs3IKSBeCN2DB7ChMc8mZuNi1EQJp2XLeHalCe_vayzX1ThIlZKOmuHR5v4_k9no7fM_MD8-i-mXumkI47MHOjjhtNsJziCi2mYAg2fjDjhysy34kbrEg362O8aYRFz2gbbiAUiEmaCl6exJIszNYkMQ_E0gfu3v1817A0L-94eZLyAUxZqcOxjNjtFS1wdFPw5TvTroUQPMW-6z4zBLnTzDGP0YC1kJklOuB9JdG9zcu82X81002FX6pdjtVxAKYpYtKiV0uTFrzY4i3OoyKoKft8pjg37Wr-6RUk_T4ryMR1v88KMnHh91lBJi7-t4J83QoS-uZC7swR2bCMZN9WQr7ozFzjxZDFMF8ZxXXOnOdrTm3pM9Wcr1Ar6tyvVymaome5TjRxv1qV-IyK64_x2Jfe9ZTVsZDjDcORx1F24J8q9a_VyCc99RVy6gar1vMXrZDncs-2cuFGfK3jqUyvuJWb4nntAIXeRuS_1Vs5_Nfayn3LtghC87ZoRZDG_-6LXmBfdJFeojRCEbkgLdtX9WXKBf5UFVVz0dbFpXrq353098f7RXE_PJxjXX2kCRO_v26aloqfZnsIROHF_hKHiZfQjEYgdUmYeUEQpFGCggBkIPCS8KIgMS2aS8vbWhCW9MGWQ_B3y7u--HYE-SV0uZcBgF0fBsDduFHswyhIIQwwJnFsYZceSF5sxDibqt5d1JdyyLjdNbyxyBvWnBpJ0-S7klIJmCNkOSvkh8k3LOL79Ir7ePebdTz-mL77HuyBy2A_0LxOp9_KXEjclxL073fGi0E>53198</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[performance] one matrix4x4 invert case with weird performance
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
deepkolos
</td>
</tr>
</table>
<pre>
it can be reproduce online or local
https://www.quick-bench.com/q/ttwEaLP3gdyX5ELER89Dc5RQ7XE
```cpp
#define REF(T) const T&
struct Matrix4 {
float elements[16] {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
};
inline Matrix4 invert(REF(Matrix4) mat4) {
Matrix4 out;
// based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm
const float n11 = mat4.elements[0], n21 = mat4.elements[1], n31 = mat4.elements[2], n41 = mat4.elements[3], n12 = mat4.elements[4],
n22 = mat4.elements[5], n32 = mat4.elements[6], n42 = mat4.elements[7], n13 = mat4.elements[8], n23 = mat4.elements[9],
n33 = mat4.elements[10], n43 = mat4.elements[11], n14 = mat4.elements[12], n24 = mat4.elements[13], n34 = mat4.elements[14],
n44 = mat4.elements[15],
t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44,
t12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44,
t13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44,
t14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;
const float det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14;
if (det == 0) {
// out.Set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
return out;
}
const float detInv = 1 / det;
out.elements[0] = t11 * detInv;
out.elements[1] = (n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44) * detInv;
out.elements[2] = (n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44) * detInv;
out.elements[3] = (n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43) * detInv;
out.elements[4] = t12 * detInv;
out.elements[5] = (n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44) * detInv;
out.elements[6] = (n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44) * detInv;
out.elements[7] = (n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43) * detInv;
out.elements[8] = t13 * detInv;
out.elements[9] = (n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44) * detInv;
out.elements[10] = (n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44) * detInv;
out.elements[11] = (n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43) * detInv;
out.elements[12] = t14 * detInv;
out.elements[13] = (n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34) * detInv;
out.elements[14] = (n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34) * detInv;
out.elements[15] = (n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33) * detInv;
return out;
}
static void BM_Matrix4_Invert(benchmark::State& state) {
Matrix4 mat4A {7, 3, 6, 9, 2, 3, 2, 5, 1, 9, 5, 8, 3, 7, 2, 2};
for (auto _ : state) {
mat4A = invert(mat4A);
mat4A.elements[0]++;
benchmark::DoNotOptimize(mat4A);
}
}
BENCHMARK(BM_Matrix4_Invert);
static void BM_Matrix4_Invert2(benchmark::State& state) {
Matrix4 mat4A {7, 3, 6, 9, 2, 3, 2, 5, 1, 9, 5, 8, 3, 7, 2, 2};
for (auto _ : state) {
mat4A.elements[0]++;
mat4A = invert(mat4A);
benchmark::DoNotOptimize(mat4A);
}
}
BENCHMARK(BM_Matrix4_Invert2);
```
the difference between two case is
```cpp
mat4A = invert(mat4A);
mat4A.elements[0]++;
// and
mat4A.elements[0]++;
mat4A = invert(mat4A);
```
![image](https://user-images.githubusercontent.com/12824616/149461218-6654ebbf-325c-4fa9-959a-560b8dba86e0.png)
but the performance diff is huge 13 times...
![image](https://user-images.githubusercontent.com/12824616/149461547-26705f6d-1aca-4e0a-ac38-5b506ed168f7.png)
BM_Matrix4_Invert's asm
```asm
push %rbp
push %r15
push %r14
push %r12
push %rbx
sub $0x80,%rsp
mov %rdi,%r14
movups -0xbf1d(%rip),%xmm0 # 20619c <benchmark::(anonymous namespace)::kBigSIUnits+0x924>
movaps %xmm0,0x30(%rsp)
movups -0xbf39(%rip),%xmm0 # 20618c <benchmark::(anonymous namespace)::kBigSIUnits+0x914>
movaps %xmm0,0x20(%rsp)
movups -0xbf55(%rip),%xmm0 # 20617c <benchmark::(anonymous namespace)::kBigSIUnits+0x904>
movaps %xmm0,0x10(%rsp)
movups -0xbf71(%rip),%xmm0 # 20616c <benchmark::(anonymous namespace)::kBigSIUnits+0x8f4>
movaps %xmm0,(%rsp)
mov 0x1a(%rdi),%bpl
mov 0x10(%rdi),%rbx
callq 213080 <benchmark::State::StartKeepRunning()>
test %bpl,%bpl
jne 21214a <BM_Matrix4_Invert(benchmark::State&)+0xaa>
test %rbx,%rbx
je 21214a <BM_Matrix4_Invert(benchmark::State&)+0xaa>
lea 0x40(%rsp),%r15
mov %rsp,%r12
mov %r15,%rdi
14.44% mov %r12,%rsi
callq 212310 <invert(Matrix4 const&)>
movups 0x40(%rsp),%xmm0
15.56% movups 0x50(%rsp),%xmm1
movups 0x60(%rsp),%xmm2
movups 0x70(%rsp),%xmm3
35.56% movaps %xmm3,0x30(%rsp)
21.67% movaps %xmm2,0x20(%rsp)
movaps %xmm1,0x10(%rsp)
movaps %xmm0,(%rsp)
movss (%rsp),%xmm0
12.22% addss -0xcf8f(%rip),%xmm0 # 2051b0 <_IO_stdin_used-0x4>
movss %xmm0,(%rsp)
0.56% add $0xffffffffffffffff,%rbx
jne 212100 <BM_Matrix4_Invert(benchmark::State&)+0x60>
mov %r14,%rdi
callq 213150 <benchmark::State::FinishKeepRunning()>
add $0x80,%rsp
pop %rbx
pop %r12
pop %r14
pop %r15
pop %rbp
retq
```
BM_Matrix4_Invert2's asm
```asm
push %rbp
push %r15
push %r14
push %r12
push %rbx
sub $0x80,%rsp
mov %rdi,%r14
movups -0xbfed(%rip),%xmm0 # 20619c <benchmark::(anonymous namespace)::kBigSIUnits+0x924>
movaps %xmm0,0x30(%rsp)
movups -0xc009(%rip),%xmm0 # 20618c <benchmark::(anonymous namespace)::kBigSIUnits+0x914>
movaps %xmm0,0x20(%rsp)
movups -0xc025(%rip),%xmm0 # 20617c <benchmark::(anonymous namespace)::kBigSIUnits+0x904>
movaps %xmm0,0x10(%rsp)
movups -0xc041(%rip),%xmm0 # 20616c <benchmark::(anonymous namespace)::kBigSIUnits+0x8f4>
movaps %xmm0,(%rsp)
mov 0x1a(%rdi),%bpl
mov 0x10(%rdi),%rbx
callq 213080 <benchmark::State::StartKeepRunning()>
test %bpl,%bpl
jne 21226a <BM_Matrix4_Invert2(benchmark::State&)+0xfa>
test %rbx,%rbx
je 21226a <BM_Matrix4_Invert2(benchmark::State&)+0xfa>
movl $0x41000000,(%rsp)
lea 0x40(%rsp),%rdi
mov %rsp,%rsi
callq 212310 <invert(Matrix4 const&)>
movups 0x40(%rsp),%xmm0
movups 0x50(%rsp),%xmm1
movups 0x60(%rsp),%xmm2
movups 0x70(%rsp),%xmm3
movaps %xmm3,0x30(%rsp)
movaps %xmm2,0x20(%rsp)
movaps %xmm1,0x10(%rsp)
movaps %xmm0,(%rsp)
add $0xffffffffffffffff,%rbx
je 21226a <BM_Matrix4_Invert2(benchmark::State&)+0xfa>
lea 0x40(%rsp),%r15
mov %rsp,%r12
nopl 0x0(%rax)
16.67% movss (%rsp),%xmm0
addss -0xd07d(%rip),%xmm0 # 2051b0 <_IO_stdin_used-0x4>
movss %xmm0,(%rsp)
mov %r15,%rdi
8.33% mov %r12,%rsi
callq 212310 <invert(Matrix4 const&)>
movups 0x40(%rsp),%xmm0
8.33% movups 0x50(%rsp),%xmm1
movups 0x60(%rsp),%xmm2
movups 0x70(%rsp),%xmm3
25.00% movaps %xmm3,0x30(%rsp)
41.67% movaps %xmm2,0x20(%rsp)
movaps %xmm1,0x10(%rsp)
movaps %xmm0,(%rsp)
add $0xffffffffffffffff,%rbx
jne 212220 <BM_Matrix4_Invert2(benchmark::State&)+0xb0>
mov %r14,%rdi
callq 213150 <benchmark::State::FinishKeepRunning()>
add $0x80,%rsp
pop %rbx
pop %r12
pop %r14
pop %r15
pop %rbp
retq
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJztWltznDgW_jX4haJLN24PfnDHTm1qJjO7zm7VvLkEqN0kNHRAxM7--pHEpZEQHex4xpPd6bKBPjqSvnPVkeikyr5e5txNaekmzK3Zsa6yNmVuVRZ5KW61W1QpLVwHXDvgqrvuOT82Dr5y0Fvx9_DwsPnc5uknL2Flut-k1UFQP4t_zh9u6M__xPfZ19_8m59vbqP4OvVv_xX-djMdzglA95cejz0F4Yzt5Py3N2KK6N8Oit3JJ63KhruCGkzHaXjdptx9T3mdPxLXCbcdXfbYFRXlLivYgZW8cfwtDBz_WvJAB71xgeXynIbw2sH9rNPnvFPmgCwvv7CaC7k66XqylPFAubpr2IduVcvHESW9U7-b0IZlwl6uNItmFdamRZ4xWjZHmrLeMGKKfSPutLhnSU07ihhfPOzaMuW50K14VhgbJqlVW18rSsYeN3t-OCHo7NDptoTQdfC1EmEzUTQQepbKKZG9HQ7t2N6OhnZib8dDO0TWdtK1n0BPPyWyd_JHUPb2YARlbw9HUNjaHo1KsbfHZ0Fjeyc4qposMIy6hsTOMCobLTCM2sYLDOfVTRZ6-ed68d6zlLLQVTe3vAvlex1URcUj1UHbCR31dKy4kTFGR8UGL-nHQMbY5AzKzhWUbg08XucIc-xwjlHNC-coO_ocpzfhXoMS9yh7XmTFgwxdjnRNl8O8SNPlOLKhy5F7DUqi63JiH2-OHevYp9rYzlFiQ5cTj_DmKDHRcu4042WM9yih4lV-qrxm-N5rDw_f-5nJ8F0fO98JctSPKgcGs6VgkvbFarD5wOQqYluKnn-JNUzyUzPe1uV8-REL3JJe3pVflGqkoG8lQespoRsrhOLmvSK7Ac51gUMXIf48AUAtpIlGHXihHli9yWYBN44y8CsnGbknrhyvhI406Gac6yDRSNUz2gAGaWD0rIhmwHVB0dOhYw26mYqgNq3dFifgOhgzdZvgsSbomITWQycnH0Mru_hTaWfpG2rp-yStli51_HDuY9OFwTAU_A4fCzToc2_yLCuMLpBhqBn0gT73sqmgz_CxUINu9abZIjhofe5lnkWPSBPfyAMz6E_wsejkY3hll9hmKGSVFlkNhRbwIyOPjaNYDYWe4WMQ2Cy1gNK0lIles5RRkqAZcl3SZzgZhLbYRtYAWbDGQoDMCicTvZYJ0DO8DKKTm5G1fbBV3lOwW0o_vGArjG22wtimHWza6lRUrZeXWGMEadjNEs8aI9i0FTHoaIbeYqsnYfetMYI1lGYZamSzCXpLxGJrjGAzG4x59Ax2S5k3lnjDAQvleep-qfLM3b6_688l7t4Nxxnq_OdA60_yFAJffRDszEGB23QPC8cacjN4JZtCWYFieQnkJZYXNNLUkz-ev8Tj12hkCUc-ND19kZPtqlragLa8cu-ERa4WQMlPD0hYbTyoUSRbbawa5scdW_ln8hrqua5-qfivR54f8v-ypTlOFhgetje_vPnH-6vbn0QXixFO3VfYDP2PGW2lIZ5i4D_BaEiz2nAYOjUi3zM3y3c7Vgs0TGDiD4yVLn-o3JQ2zM0b7Xx2fqC6TuQ1OhwOaNUelJbZlLrOCGugWLXgILFsb_MDvWdq2Eg_h24bVnuqtdnc53zfJpIiNqZcgOkPPyGKEAlgIB9JLJ4QjLwg8AlLkp2HkZ96ZEdjL_Zj6vkBSKIsoVHAwOZY3kuAEzhJy11pmCOrhaMeqLSMNJK0xr69Z67I4MJPBJrN5o8Wwyehh4IQ-Lsg8yBNqUcYoB5NceT5iQ8ClsEg2oUWMXoHnWeSsHFpc7D61Ujvg-TYNnt1MuHXyXGpRSyGSy1ksQUtzvOotTRtoiIPEfCoDkQkT6NjOVRf3L53lvcsxtSCpT02rgcekx3MhG0kT36UKlP8j4cDGDKDI9ZgBAIYp8KZ3xh5Qqatsiq_Hqq2cUsqvEAewSsXl82ftvn9h3f_KXMRJWgLHmNEHHxjQqECSj-pmB48YtAjao6jES3AcbwOePQSwOEa4GgdcN9fBzx8CeBgDXC4DngI1wEPXgB4tPs28HOg5U0IRnseGQk94uRYLDCDObMZgCktis-uiyAGEbBI2dUVw2PNf2LseNuWZS4TUqSk1YXirOFdtEpcVoAfSyZvSGRxQuWcTyhKlSBCnZQuTyxltAr7Uc370hMXjHb6JrrX9ZnKX0pmkuuNJVtOWKDfswgLKhZINnLD7GtMaMibud20CENl2nHdHqpBdfrbyzb3TRkmdqGUu3Z4_I0f9Hg6ft_OD-2jB3bumUI67tDOjTtuPMFyiiu8mIIR3AThjB-tyHwnbrgi3ayP8aaRFj2jbbRBSCKmWSZ5RRJLd9FuTRLzYaJ84O7dr3cNz_LyTpQnmRjAlpU6HMuIQa9oiaObQizfO-OzEIKn2AfgmSEonGaOeYwGYoTMLNFB_xuJ7m1e5s3-m5luKvxS7XKsjgMwQxGTFrNamrSQxRZ_cR4dQc345zPFuW1X8_9eQbIfs4JMAfgxK8gUoB-zgkwB-buCfN0KEgX2Qu7MEdmwjOy-r4R80ZmFxoshixGxMsrPOXOerzmNpc9Wc75CrWhyv16laIue5TrRxv1qVeIzKq4_xmNfetdTVsdCjTcMRx9H2WFwqtS_VSOf9NRXyBkIV63nL1ohz-WebeWijXyt4-tMr7iVm-J57QBF_kbmv9VbOfLX2sp9z7YIIfu2aEWQJn_vi15gX3SRXeIsxjG94Dkv2KXjbyevCuSL4UoYq_vxNRl_Fd690HnI-d59YHmdTV8vXLR1cam_LejeEPSvBYriy3DzjnX1kaVc_m67aVomf9LtYxhHF_vLIPATPwmSkGIW4h0AQZTGOxQzEAQ0IuSioAkrGgnYQahkD64aQjwL0Bf5JQLCtyAkIEAhBBsQJwGKwwyhkBCaJA4B7EDzYiNxbKr6_qK-VJCS9r4RjUXe8ObUSJsmvy-Z0o8cn7Z8X9WXmfCOT1VRNRdq8ksF_neZOnVZ">