mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 10:51:54 -04:00
Refactors vector operations.
This commit is contained in:
parent
29b411e3fe
commit
cae803bdfb
10 changed files with 75 additions and 76 deletions
2
check.c
2
check.c
|
|
@ -488,7 +488,7 @@ static int state_check_process(struct snapraid_state* state, int check, int fix,
|
|||
|
||||
buffer = malloc_nofail_vector_align(diskmax, buffermax, state->block_size, &buffer_alloc);
|
||||
if (!state->opt.skip_self)
|
||||
mtest_vector(buffer, buffermax, state->block_size);
|
||||
mtest_vector(buffermax, state->block_size, buffer);
|
||||
|
||||
/* fill up the zero buffer */
|
||||
memset(buffer[buffermax-1], 0, state->block_size);
|
||||
|
|
|
|||
|
|
@ -34,41 +34,53 @@ void *raid_malloc_align(size_t size, void **freeptr)
|
|||
return ptr;
|
||||
}
|
||||
|
||||
void **raid_malloc_vector(size_t reverse, size_t count, size_t size, void **freeptr)
|
||||
void **raid_malloc_vector(int nd, int n, size_t size, void **freeptr)
|
||||
{
|
||||
void **v;
|
||||
unsigned char *va;
|
||||
size_t i;
|
||||
int i;
|
||||
|
||||
assert(reverse <= count);
|
||||
|
||||
v = malloc(count * sizeof(void *));
|
||||
v = malloc(n * sizeof(void *));
|
||||
if (!v)
|
||||
return 0;
|
||||
|
||||
va = raid_malloc_align(count * (size + RAID_MALLOC_DISPLACEMENT), freeptr);
|
||||
va = raid_malloc_align(n * (size + RAID_MALLOC_DISPLACEMENT), freeptr);
|
||||
if (!va) {
|
||||
free(v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; ++i)
|
||||
v[i] = va + i * (size + RAID_MALLOC_DISPLACEMENT);
|
||||
for (i = 0; i < n; ++i) {
|
||||
v[i] = va;
|
||||
va += size + RAID_MALLOC_DISPLACEMENT;
|
||||
}
|
||||
|
||||
/* reverse order for the initial ones */
|
||||
for (i = 0; i < reverse/2; ++i) {
|
||||
/* reverse order of the data blocks */
|
||||
/* because they are usually accessed from the last one */
|
||||
for (i = 0; i < nd/2; ++i) {
|
||||
void *ptr = v[i];
|
||||
v[i] = v[reverse - 1 - i];
|
||||
v[reverse - 1 - i] = ptr;
|
||||
v[i] = v[nd - 1 - i];
|
||||
v[nd - 1 - i] = ptr;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
int raid_mtest_vector(void **vv, size_t count, size_t size)
|
||||
void raid_mrand_vector(int n, size_t size, void **vv)
|
||||
{
|
||||
unsigned char **v = (unsigned char **)vv;
|
||||
size_t i;
|
||||
int i;
|
||||
size_t j;
|
||||
|
||||
for (i = 0; i < n; ++i)
|
||||
for (j = 0; j < size; ++j)
|
||||
v[i][j] = rand();
|
||||
}
|
||||
|
||||
int raid_mtest_vector(int n, size_t size, void **vv)
|
||||
{
|
||||
unsigned char **v = (unsigned char **)vv;
|
||||
int i;
|
||||
size_t j;
|
||||
unsigned k;
|
||||
unsigned char d;
|
||||
|
|
@ -76,7 +88,7 @@ int raid_mtest_vector(void **vv, size_t count, size_t size)
|
|||
|
||||
/* fill with 0 */
|
||||
d = 0;
|
||||
for (i = 0; i < count; ++i)
|
||||
for (i = 0; i < n; ++i)
|
||||
for (j = 0; j < size; ++j)
|
||||
v[i][j] = d;
|
||||
|
||||
|
|
@ -86,7 +98,7 @@ int raid_mtest_vector(void **vv, size_t count, size_t size)
|
|||
d = k;
|
||||
|
||||
/* forward fill */
|
||||
for (i = 0; i < count; ++i) {
|
||||
for (i = 0; i < n; ++i) {
|
||||
for (j = 0; j < size; ++j) {
|
||||
if (v[i][j] != p)
|
||||
return -1;
|
||||
|
|
@ -97,7 +109,7 @@ int raid_mtest_vector(void **vv, size_t count, size_t size)
|
|||
p = d;
|
||||
d = ~p;
|
||||
/* backward fill with complement */
|
||||
for (i = 0; i < count; ++i) {
|
||||
for (i = 0; i < n; ++i) {
|
||||
for (j = size; j > 0; --j) {
|
||||
if (v[i][j-1] != p)
|
||||
return -1;
|
||||
|
|
@ -109,14 +121,3 @@ int raid_mtest_vector(void **vv, size_t count, size_t size)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void raid_mrand_vector(void **vv, size_t count, size_t size)
|
||||
{
|
||||
unsigned char **v = (unsigned char **)vv;
|
||||
size_t i;
|
||||
size_t j;
|
||||
|
||||
for (i = 0; i < count; ++i)
|
||||
for (j = 0; j < size; ++j)
|
||||
v[i][j] = rand();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,26 +28,27 @@
|
|||
*
|
||||
* When allocating a sequence of blocks with a size of power of 2,
|
||||
* there is the risk that the start of each block is mapped into the same
|
||||
* cache line, resulting in cache collisions if you access all the blocks
|
||||
* in parallel, from the start to the end.
|
||||
* cache line or prefetching prediction, resulting in collisions if you
|
||||
* access all the blocks in parallel, from the start to the end.
|
||||
*
|
||||
* The selected value was choosen empirically with some speed tests
|
||||
* with 8/12/16/20/24 data buffers of 256 KB.
|
||||
*
|
||||
* With displacement:
|
||||
* (8 buffers of 256 KB, icore5, 32 bits):
|
||||
* These are the results with no displacement:
|
||||
*
|
||||
* sse2
|
||||
* par1 21936 [MB/s]
|
||||
* par2 11902 [MB/s]
|
||||
* parz 5838 [MB/s]
|
||||
* sse2
|
||||
* par1 15368 [MB/s]
|
||||
* par2 6814 [MB/s]
|
||||
* parz 3033 [MB/s]
|
||||
*
|
||||
* Without displacement:
|
||||
* These are the results with displacement resulting in improvments
|
||||
* in the order of 20% or more:
|
||||
*
|
||||
* sse2
|
||||
* par1 21936 [MB/s]
|
||||
* par2 11902 [MB/s]
|
||||
* parz 5838 [MB/s]
|
||||
*
|
||||
* sse2
|
||||
* par1 15368 [MB/s]
|
||||
* par2 6814 [MB/s]
|
||||
* parz 3033 [MB/s]
|
||||
*/
|
||||
#define RAID_MALLOC_DISPLACEMENT (7*256)
|
||||
|
||||
|
|
@ -58,22 +59,22 @@ void *raid_malloc_align(size_t size, void **freeptr);
|
|||
|
||||
/**
|
||||
* Aligned vector allocation.
|
||||
* Returns a vector of "count" pointers, each one pointing to a block of the
|
||||
* specified "size".
|
||||
* The first "reverse" pointers are put in reverse memory offset order.
|
||||
* Returns a vector of ::n pointers, each one pointing to a block of
|
||||
* the specified ::size.
|
||||
* The first ::nd elements are reversed in order.
|
||||
*/
|
||||
void **raid_malloc_vector(size_t reverse, size_t count, size_t size, void **freeptr);
|
||||
void **raid_malloc_vector(int nd, int n, size_t size, void **freeptr);
|
||||
|
||||
/**
|
||||
* Fills the memory vector with random data.
|
||||
*/
|
||||
void raid_mrand_vector(int n, size_t size, void **vv);
|
||||
|
||||
/**
|
||||
* Tests the memory vector for RAM problems.
|
||||
* If a problem is found, it crashes.
|
||||
*/
|
||||
int raid_mtest_vector(void **vv, size_t count, size_t size);
|
||||
|
||||
/**
|
||||
* Fills the memory vector with random data.
|
||||
*/
|
||||
void raid_mrand_vector(void **vv, size_t count, size_t size);
|
||||
int raid_mtest_vector(int n, size_t size, void **vv);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ int raid_selftest(void)
|
|||
/* test parity generation */
|
||||
ret = raid_test_par(nd, np, size, v, ref);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
goto bail;
|
||||
|
||||
/* test recovering with full broken data disks */
|
||||
for (i = 0; i < np; ++i)
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ int raid_test_rec(int mode, int nd, size_t size)
|
|||
waste = v[nv-1];
|
||||
|
||||
/* fill data disk with random */
|
||||
raid_mrand_vector(v, nd, size);
|
||||
raid_mrand_vector(nd, size, v);
|
||||
|
||||
/* setup recov functions */
|
||||
for (i = 0; i < np; ++i) {
|
||||
|
|
@ -253,7 +253,7 @@ int raid_test_par(int mode, int nd, size_t size)
|
|||
return -1;
|
||||
|
||||
/* fill with random */
|
||||
raid_mrand_vector(v, nv, size);
|
||||
raid_mrand_vector(nv, size, v);
|
||||
|
||||
/* compute the parity */
|
||||
raid_par_ref(nd, np, size, v);
|
||||
|
|
|
|||
2
scrub.c
2
scrub.c
|
|
@ -69,7 +69,7 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par
|
|||
|
||||
buffer = malloc_nofail_vector_align(diskmax, buffermax, state->block_size, &buffer_alloc);
|
||||
if (!state->opt.skip_self)
|
||||
mtest_vector(buffer, buffermax, state->block_size);
|
||||
mtest_vector(buffermax, state->block_size, buffer);
|
||||
|
||||
error = 0;
|
||||
silent_error = 0;
|
||||
|
|
|
|||
1
speed.c
1
speed.c
|
|
@ -81,7 +81,6 @@ void speed(void)
|
|||
void *v_alloc;
|
||||
void **v;
|
||||
|
||||
/* we need disk + 1 for each parity buffers + 1 zero v */
|
||||
nv = nd + RAID_PARITY_MAX + 1;
|
||||
|
||||
v = malloc_nofail_vector_align(nd, nv, size, &v_alloc);
|
||||
|
|
|
|||
2
sync.c
2
sync.c
|
|
@ -76,7 +76,7 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari
|
|||
|
||||
buffer = malloc_nofail_vector_align(diskmax, buffermax, state->block_size, &buffer_alloc);
|
||||
if (!state->opt.skip_self)
|
||||
mtest_vector(buffer, buffermax, state->block_size);
|
||||
mtest_vector(buffermax, state->block_size, buffer);
|
||||
|
||||
error = 0;
|
||||
silent_error = 0;
|
||||
|
|
|
|||
18
util.c
18
util.c
|
|
@ -1384,11 +1384,11 @@ void* malloc_nofail_align(size_t size, void** freeptr)
|
|||
return ptr;
|
||||
}
|
||||
|
||||
void** malloc_nofail_vector_align(size_t reverse, size_t count, size_t size, void** freeptr)
|
||||
void** malloc_nofail_vector_align(int nd, int n, size_t size, void** freeptr)
|
||||
{
|
||||
void* ptr;
|
||||
|
||||
ptr = raid_malloc_vector(reverse, count, size, freeptr);
|
||||
ptr = raid_malloc_vector(nd, n, size, freeptr);
|
||||
|
||||
if (!ptr) {
|
||||
/* don't use printf to avoid any possible extra allocation */
|
||||
|
|
@ -1401,20 +1401,20 @@ void** malloc_nofail_vector_align(size_t reverse, size_t count, size_t size, voi
|
|||
return ptr;
|
||||
}
|
||||
|
||||
void mtest_vector(void** vv, size_t count, size_t size)
|
||||
void mrand_vector(int n , size_t size, void** vv)
|
||||
{
|
||||
if (raid_mtest_vector(vv, count, size) != 0) {
|
||||
raid_mrand_vector(n, size, vv);
|
||||
}
|
||||
|
||||
void mtest_vector(int n , size_t size, void** vv)
|
||||
{
|
||||
if (raid_mtest_vector(n, size, vv) != 0) {
|
||||
fprintf(stderr, "DANGER! Your RAM memory is broken! DO NOT PROCEED UNTIL FIXED!\n");
|
||||
fprintf(stderr, "Try running some memory test like http://www.memtest86.com/\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
void mrand_vector(void** vv, size_t count, size_t size)
|
||||
{
|
||||
raid_mrand_vector(vv, count, size);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* byte operations */
|
||||
|
||||
|
|
|
|||
16
util.h
16
util.h
|
|
@ -466,22 +466,20 @@ void* malloc_nofail_align(size_t size, void** freeptr);
|
|||
|
||||
/**
|
||||
* Safe aligned vector allocation.
|
||||
* Returns a vector of "count" pointers, each one pointing to a block of the specified "size".
|
||||
* The first "reverse" pointers are put in reverse memory offset order.
|
||||
* If no memory is available, it aborts.
|
||||
*/
|
||||
void** malloc_nofail_vector_align(size_t reverse, size_t count, size_t size, void** freeptr);
|
||||
void** malloc_nofail_vector_align(int nd, int n, size_t size, void** freeptr);
|
||||
|
||||
/**
|
||||
* Fills the memory vector with random data.
|
||||
*/
|
||||
void mrand_vector(int n, size_t size, void** vv);
|
||||
|
||||
/**
|
||||
* Tests the memory vector for RAM problems.
|
||||
* If a problem is found, it crashes.
|
||||
*/
|
||||
void mtest_vector(void** vv, size_t count, size_t size);
|
||||
|
||||
/**
|
||||
* Fills the memory vector with random data.
|
||||
*/
|
||||
void mrand_vector(void** vv, size_t count, size_t size);
|
||||
void mtest_vector(int n, size_t size, void** vv);
|
||||
|
||||
/**
|
||||
* Safe strdup.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue