| 323 | // |
| 324 | |
| 325 | inline void DoSplitStreams(const uint8_t* src, int width, int64_t nvalues, |
| 326 | uint8_t** dest_streams) { |
| 327 | // Value empirically chosen to provide the best performance on the author's machine |
| 328 | constexpr int kBlockSize = 32; |
| 329 | |
| 330 | while (nvalues >= kBlockSize) { |
| 331 | for (int stream = 0; stream < width; ++stream) { |
| 332 | uint8_t* dest = dest_streams[stream]; |
| 333 | for (int i = 0; i < kBlockSize; i += 8) { |
| 334 | uint64_t a = src[stream + i * width]; |
| 335 | uint64_t b = src[stream + (i + 1) * width]; |
| 336 | uint64_t c = src[stream + (i + 2) * width]; |
| 337 | uint64_t d = src[stream + (i + 3) * width]; |
| 338 | uint64_t e = src[stream + (i + 4) * width]; |
| 339 | uint64_t f = src[stream + (i + 5) * width]; |
| 340 | uint64_t g = src[stream + (i + 6) * width]; |
| 341 | uint64_t h = src[stream + (i + 7) * width]; |
| 342 | #if ARROW_LITTLE_ENDIAN |
| 343 | uint64_t r = a | (b << 8) | (c << 16) | (d << 24) | (e << 32) | (f << 40) | |
| 344 | (g << 48) | (h << 56); |
| 345 | #else |
| 346 | uint64_t r = (a << 56) | (b << 48) | (c << 40) | (d << 32) | (e << 24) | |
| 347 | (f << 16) | (g << 8) | h; |
| 348 | #endif |
| 349 | arrow::util::SafeStore(&dest[i], r); |
| 350 | } |
| 351 | dest_streams[stream] += kBlockSize; |
| 352 | } |
| 353 | src += width * kBlockSize; |
| 354 | nvalues -= kBlockSize; |
| 355 | } |
| 356 | |
| 357 | // Epilog |
| 358 | for (int stream = 0; stream < width; ++stream) { |
| 359 | uint8_t* dest = dest_streams[stream]; |
| 360 | for (int64_t i = 0; i < nvalues; ++i) { |
| 361 | dest[i] = src[stream + i * width]; |
| 362 | } |
| 363 | } |
| 364 | } |
| 365 | |
| 366 | inline void DoMergeStreams(const uint8_t** src_streams, int width, int64_t nvalues, |
| 367 | uint8_t* dest) { |
no test coverage detected