Reduce memory allocations when generating the merkle root
When generating the merkle root, the previous code calls `malloc` once for every transaction, which is not ideal for performance. The new code allocates a 32 KiB buffer once and reuses it for all transactions. If a TX is bigger than the current buffer size, the buffer is reallocated with double the current buffer size.
This commit is contained in:
parent
173a497e60
commit
6661ca7e1b
1 changed files with 10 additions and 3 deletions
13
cpu-miner.c
13
cpu-miner.c
|
@ -351,6 +351,7 @@ static bool gbt_work_decode(const json_t *val, struct work *work)
|
||||||
uint32_t target[8];
|
uint32_t target[8];
|
||||||
int cbtx_size;
|
int cbtx_size;
|
||||||
unsigned char *cbtx = NULL;
|
unsigned char *cbtx = NULL;
|
||||||
|
unsigned char *tx = NULL;
|
||||||
int tx_count, tx_size;
|
int tx_count, tx_size;
|
||||||
unsigned char txc_vi[9];
|
unsigned char txc_vi[9];
|
||||||
unsigned char (*merkle_tree)[32] = NULL;
|
unsigned char (*merkle_tree)[32] = NULL;
|
||||||
|
@ -581,6 +582,8 @@ static bool gbt_work_decode(const json_t *val, struct work *work)
|
||||||
|
|
||||||
/* generate merkle root */
|
/* generate merkle root */
|
||||||
merkle_tree = malloc(32 * ((1 + tx_count + 1) & ~1));
|
merkle_tree = malloc(32 * ((1 + tx_count + 1) & ~1));
|
||||||
|
size_t tx_buf_size = 32 * 1024;
|
||||||
|
tx = malloc(tx_buf_size);
|
||||||
sha256d(merkle_tree[0], cbtx, cbtx_size);
|
sha256d(merkle_tree[0], cbtx, cbtx_size);
|
||||||
for (i = 0; i < tx_count; i++) {
|
for (i = 0; i < tx_count; i++) {
|
||||||
tmp = json_array_get(txa, i);
|
tmp = json_array_get(txa, i);
|
||||||
|
@ -594,18 +597,21 @@ static bool gbt_work_decode(const json_t *val, struct work *work)
|
||||||
}
|
}
|
||||||
memrev(merkle_tree[1 + i], 32);
|
memrev(merkle_tree[1 + i], 32);
|
||||||
} else {
|
} else {
|
||||||
unsigned char *tx = malloc(tx_size);
|
if (tx_size > tx_buf_size) {
|
||||||
|
free(tx);
|
||||||
|
tx_buf_size = tx_size * 2;
|
||||||
|
tx = malloc(tx_buf_size);
|
||||||
|
}
|
||||||
if (!tx_hex || !hex2bin(tx, tx_hex, tx_size)) {
|
if (!tx_hex || !hex2bin(tx, tx_hex, tx_size)) {
|
||||||
applog(LOG_ERR, "JSON invalid transactions");
|
applog(LOG_ERR, "JSON invalid transactions");
|
||||||
free(tx);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
sha256d(merkle_tree[1 + i], tx, tx_size);
|
sha256d(merkle_tree[1 + i], tx, tx_size);
|
||||||
free(tx);
|
|
||||||
}
|
}
|
||||||
if (!submit_coinbase)
|
if (!submit_coinbase)
|
||||||
strcat(work->txs, tx_hex);
|
strcat(work->txs, tx_hex);
|
||||||
}
|
}
|
||||||
|
free(tx); tx = NULL;
|
||||||
n = 1 + tx_count;
|
n = 1 + tx_count;
|
||||||
while (n > 1) {
|
while (n > 1) {
|
||||||
if (n % 2) {
|
if (n % 2) {
|
||||||
|
@ -662,6 +668,7 @@ static bool gbt_work_decode(const json_t *val, struct work *work)
|
||||||
rc = true;
|
rc = true;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
free(tx);
|
||||||
free(cbtx);
|
free(cbtx);
|
||||||
free(merkle_tree);
|
free(merkle_tree);
|
||||||
return rc;
|
return rc;
|
||||||
|
|
Loading…
Reference in a new issue