| 326 | |
| 327 | #ifdef _sse2_ |
| 328 | inline void AddFeaturesProduct(const double weight, const TVector<double>& features, TVector<double>& linearizedOLSTriangleMatrix) { |
| 329 | const double* leftFeature = features.data(); |
| 330 | const double* featuresEnd = features.data() + features.size(); |
| 331 | double* matrixElement = linearizedOLSTriangleMatrix.data(); |
| 332 | |
| 333 | size_t unaligned = features.size() & 0x1; |
| 334 | |
| 335 | for (; leftFeature != featuresEnd; ++leftFeature, ++matrixElement) { |
| 336 | const double weightedFeature = weight * *leftFeature; |
| 337 | const double* rightFeature = leftFeature; |
| 338 | __m128d wf = {weightedFeature, weightedFeature}; |
| 339 | for (size_t i = 0; i < unaligned; ++i, ++rightFeature, ++matrixElement) { |
| 340 | *matrixElement += weightedFeature * *rightFeature; |
| 341 | } |
| 342 | unaligned = (unaligned + 1) & 0x1; |
| 343 | for (; rightFeature != featuresEnd; rightFeature += 2, matrixElement += 2) { |
| 344 | __m128d rf = _mm_loadu_pd(rightFeature); |
| 345 | __m128d matrixRow = _mm_loadu_pd(matrixElement); |
| 346 | __m128d rowAdd = _mm_mul_pd(rf, wf); |
| 347 | _mm_storeu_pd(matrixElement, _mm_add_pd(rowAdd, matrixRow)); |
| 348 | } |
| 349 | *matrixElement += weightedFeature; |
| 350 | } |
| 351 | linearizedOLSTriangleMatrix.back() += weight; |
| 352 | } |
| 353 | #else |
| 354 | inline void AddFeaturesProduct(const double weight, const TVector<double>& features, TVector<double>& linearizedTriangleMatrix) { |
| 355 | const double* leftFeature = features.data(); |
no test coverage detected