Buckets:
agent-collaborations/hutter-prize-67 / decoder-bundle-minimization /work /paq8px-src /src /LMS_SSE2.cpp
| | |
| // Static helper functions | |
| static float horizontal_sum(__m128 sum_low, __m128 sum_high) { | |
| __m128 sum128 = _mm_add_ps(sum_low, sum_high); | |
| sum128 = _mm_add_ps(sum128, _mm_movehl_ps(sum128, sum128)); | |
| sum128 = _mm_add_ss(sum128, _mm_shuffle_ps(sum128, sum128, 0x55)); | |
| float sum = _mm_cvtss_f32(sum128); | |
| return sum; | |
| } | |
| // Member implementations | |
| float LMS_SSE2::predict(const int sample) { | |
| // Shift other-channel history (the 'd' component) | |
| memmove(&buffer[s + 1], &buffer[s], (d - 1) * sizeof(float)); | |
| buffer[s] = static_cast<float>(sample); | |
| // Compute weighted prediction | |
| __m128 sum_low = _mm_setzero_ps(); | |
| __m128 sum_high = _mm_setzero_ps(); | |
| const size_t len = s + d; | |
| for (size_t i = 0; i < len; i += 8) { | |
| __m128 w0 = _mm_load_ps(&weights[i]); | |
| __m128 b0 = _mm_load_ps(&buffer[i]); | |
| __m128 prod0 = _mm_mul_ps(w0, b0); | |
| sum_low = _mm_add_ps(sum_low, prod0); | |
| __m128 w1 = _mm_load_ps(&weights[i + 4]); | |
| __m128 b1 = _mm_load_ps(&buffer[i + 4]); | |
| __m128 prod1 = _mm_mul_ps(w1, b1); | |
| sum_high = _mm_add_ps(sum_high, prod1); | |
| } | |
| float total = horizontal_sum(sum_low, sum_high); | |
| prediction = total; | |
| return total; | |
| } | |
| void LMS_SSE2::update(const int sample) { | |
| const float error = static_cast<float>(sample) - prediction; | |
| const float complement = 1.0f - rho; | |
| const __m128 v_error = _mm_set1_ps(error); | |
| const __m128 v_rho = _mm_set1_ps(rho); | |
| const __m128 v_complement = _mm_set1_ps(complement); | |
| const __m128 v_eps = _mm_set1_ps(eps); | |
| const __m128 v_sameRate = _mm_set1_ps(sameChannelRate); | |
| const __m128 v_otherRate = _mm_set1_ps(otherChannelRate); | |
| // Update same-channel weights (indices 0 to s-1) | |
| for (size_t i = 0; i < s; i += 8) { | |
| // First 4 floats | |
| __m128 b0 = _mm_load_ps(&buffer[i]); | |
| __m128 w0 = _mm_load_ps(&weights[i]); | |
| __m128 e0 = _mm_load_ps(&eg[i]); | |
| __m128 gradient0 = _mm_mul_ps(v_error, b0); | |
| __m128 grad_sq0 = _mm_mul_ps(gradient0, gradient0); | |
| e0 = _mm_add_ps(_mm_mul_ps(v_rho, e0), _mm_mul_ps(v_complement, grad_sq0)); | |
| _mm_store_ps(&eg[i], e0); | |
| __m128 denom0 = _mm_sqrt_ps(_mm_add_ps(e0, v_eps)); | |
| w0 = _mm_add_ps(w0, _mm_mul_ps(v_sameRate, _mm_div_ps(gradient0, denom0))); | |
| _mm_store_ps(&weights[i], w0); | |
| // Second 4 floats | |
| __m128 b1 = _mm_load_ps(&buffer[i + 4]); | |
| __m128 w1 = _mm_load_ps(&weights[i + 4]); | |
| __m128 e1 = _mm_load_ps(&eg[i + 4]); | |
| __m128 gradient1 = _mm_mul_ps(v_error, b1); | |
| __m128 grad_sq1 = _mm_mul_ps(gradient1, gradient1); | |
| e1 = _mm_add_ps(_mm_mul_ps(v_rho, e1), _mm_mul_ps(v_complement, grad_sq1)); | |
| _mm_store_ps(&eg[i + 4], e1); | |
| __m128 denom1 = _mm_sqrt_ps(_mm_add_ps(e1, v_eps)); | |
| w1 = _mm_add_ps(w1, _mm_mul_ps(v_sameRate, _mm_div_ps(gradient1, denom1))); | |
| _mm_store_ps(&weights[i + 4], w1); | |
| } | |
| // Update other-channel weights (indices s to s+d-1) | |
| for (size_t i = s; i < s + d; i += 8) { | |
| // First 4 floats | |
| __m128 b0 = _mm_load_ps(&buffer[i]); | |
| __m128 w0 = _mm_load_ps(&weights[i]); | |
| __m128 e0 = _mm_load_ps(&eg[i]); | |
| __m128 gradient0 = _mm_mul_ps(v_error, b0); | |
| __m128 grad_sq0 = _mm_mul_ps(gradient0, gradient0); | |
| e0 = _mm_add_ps(_mm_mul_ps(v_rho, e0), _mm_mul_ps(v_complement, grad_sq0)); | |
| _mm_store_ps(&eg[i], e0); | |
| __m128 denom0 = _mm_sqrt_ps(_mm_add_ps(e0, v_eps)); | |
| w0 = _mm_add_ps(w0, _mm_mul_ps(v_otherRate, _mm_div_ps(gradient0, denom0))); | |
| _mm_store_ps(&weights[i], w0); | |
| // Second 4 floats | |
| __m128 b1 = _mm_load_ps(&buffer[i + 4]); | |
| __m128 w1 = _mm_load_ps(&weights[i + 4]); | |
| __m128 e1 = _mm_load_ps(&eg[i + 4]); | |
| __m128 gradient1 = _mm_mul_ps(v_error, b1); | |
| __m128 grad_sq1 = _mm_mul_ps(gradient1, gradient1); | |
| e1 = _mm_add_ps(_mm_mul_ps(v_rho, e1), _mm_mul_ps(v_complement, grad_sq1)); | |
| _mm_store_ps(&eg[i + 4], e1); | |
| __m128 denom1 = _mm_sqrt_ps(_mm_add_ps(e1, v_eps)); | |
| w1 = _mm_add_ps(w1, _mm_mul_ps(v_otherRate, _mm_div_ps(gradient1, denom1))); | |
| _mm_store_ps(&weights[i + 4], w1); | |
| } | |
| // Shift same-channel history | |
| memmove(&buffer[1], &buffer[0], (s - 1) * sizeof(float)); | |
| buffer[0] = static_cast<float>(sample); | |
| } | |
Xet Storage Details
- Size:
- 4.26 kB
- Xet hash:
- 8505c5c063f8e9c82a77a74fcfa012f7f3bbf65e32f7c0e1b9c18546b6dd89b3
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.