I am working with audio data. I'd like to play the sample file in reverse. The data is stored as unsigned ints and packed nice and tight. Is there a way to call memcpy
that will copy in reverse order. i.e. if I had 1,2,3,4 stored in an array, could I call memcpy
and magically reverse them so I get 4,3,2,1.
This works for copying int
s in reverse:
void reverse_intcpy(int *restrict dst, const int *restrict src, size_t n)
{
size_t i;
for (i=0; i < n; ++i)
dst[n-1-i] = src[i];
}
Just like memcpy()
, the regions pointed-to by dst
and src
must not overlap.
If you want to reverse in-place:
void reverse_ints(int *data, size_t n)
{
size_t i;
for (i=0; i < n/2; ++i) {
int tmp = data[i];
data[i] = data[n - 1 - i];
data[n - 1 - i] = tmp;
}
}
Both the functions above are portable. You might be able to make them faster by using hardware-specific code.
(I haven't tested the code for correctness.)
memcpy
should be O(n) and so should this reverse_memcpy
function. –
Nary -O3
optimization, reverse_memcpy()
is about 3 times slower than memcpy()
for copying 1000000 bytes. For 10000 iterations with 1000000 bytes, memcpy()
took 4 seconds, and reverse_memcpy()
took 11. But these numbers are for a very specific case, so you may want to test things for yourself. Of course, as dreamlax said, both are O(n). –
Ardenia memcpy
probably works faster by copying aligned chunks of memory (when it can). –
Nary memcpy
will have the same result, as it assumes the two pointers do not overlap and is optimized on that assumption. The standard library memmove
is used in the specific case where the two pointers may point to overlapping space. If the OP wants memmove
-like behavior, he should specify it. If the OP wants reverse-in-place behavior, he should specify that as well, as that case can possibly be optimized. –
Confidence restrict
keyword in C99... –
Ardenia restrict
ing the arguments. –
Ditch void reverse_ints(int *data, size_t n) { if (n < 2) return; for (size_t i=0, j=n-1; i < j; ++i, --j) { int tmp = data[i]; data[i] = data[j]; data[j] = tmp; } }
–
Wentzel memcpy
. Keeping memory caches, SSE, and such in mind, this solution is going to be slow. And as Nuzzolilo says, big-O isn't the question here. –
Trager No, memcpy won't do that backwards. If you're working in C, write a function to do it. If you're really working in C++ use std::reverse or std::reverse_copy.
This works for copying int
s in reverse:
void reverse_intcpy(int *restrict dst, const int *restrict src, size_t n)
{
size_t i;
for (i=0; i < n; ++i)
dst[n-1-i] = src[i];
}
Just like memcpy()
, the regions pointed-to by dst
and src
must not overlap.
If you want to reverse in-place:
void reverse_ints(int *data, size_t n)
{
size_t i;
for (i=0; i < n/2; ++i) {
int tmp = data[i];
data[i] = data[n - 1 - i];
data[n - 1 - i] = tmp;
}
}
Both the functions above are portable. You might be able to make them faster by using hardware-specific code.
(I haven't tested the code for correctness.)
memcpy
should be O(n) and so should this reverse_memcpy
function. –
Nary -O3
optimization, reverse_memcpy()
is about 3 times slower than memcpy()
for copying 1000000 bytes. For 10000 iterations with 1000000 bytes, memcpy()
took 4 seconds, and reverse_memcpy()
took 11. But these numbers are for a very specific case, so you may want to test things for yourself. Of course, as dreamlax said, both are O(n). –
Ardenia memcpy
probably works faster by copying aligned chunks of memory (when it can). –
Nary memcpy
will have the same result, as it assumes the two pointers do not overlap and is optimized on that assumption. The standard library memmove
is used in the specific case where the two pointers may point to overlapping space. If the OP wants memmove
-like behavior, he should specify it. If the OP wants reverse-in-place behavior, he should specify that as well, as that case can possibly be optimized. –
Confidence restrict
keyword in C99... –
Ardenia restrict
ing the arguments. –
Ditch void reverse_ints(int *data, size_t n) { if (n < 2) return; for (size_t i=0, j=n-1; i < j; ++i, --j) { int tmp = data[i]; data[i] = data[j]; data[j] = tmp; } }
–
Wentzel memcpy
. Keeping memory caches, SSE, and such in mind, this solution is going to be slow. And as Nuzzolilo says, big-O isn't the question here. –
Trager © 2022 - 2024 — McMap. All rights reserved.