mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-05 16:00:05 +01:00
Rewrite cipher benchmark loop.
Using getrusage seems toi give not adequate precision, so use clock_gettime and try to scale buffer size a bit on high performance systems. If it still fail, return ERANGE error instead calculating completely unreliable numbers. Should fix Issue#186.
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
* libcryptsetup - cryptsetup library, cipher bechmark
|
||||
*
|
||||
* Copyright (C) 2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012, Milan Broz
|
||||
* Copyright (C) 2012-2013, Milan Broz
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -21,8 +21,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -32,6 +31,12 @@
|
||||
*/
|
||||
#define CIPHER_BLOCK_BYTES 65536
|
||||
|
||||
/*
|
||||
* If the measured value is lower, encrypted buffer is probably too small
|
||||
* and calculated values are not reliable.
|
||||
*/
|
||||
#define CIPHER_TIME_MIN_MS 0.001
|
||||
|
||||
/*
|
||||
* The whole test depends on Linux kernel usermode crypto API for now.
|
||||
* (The same implementations are used in dm-crypt though.)
|
||||
@@ -47,19 +52,15 @@ struct cipher_perf {
|
||||
size_t buffer_size;
|
||||
};
|
||||
|
||||
static long time_ms(struct rusage *start, struct rusage *end)
|
||||
static int time_ms(struct timespec *start, struct timespec *end, double *ms)
|
||||
{
|
||||
long ms = 0;
|
||||
double start_ms, end_ms;
|
||||
|
||||
/* For kernel backend, we need to measure only tim in kernel.
|
||||
ms = (end->ru_utime.tv_sec - start->ru_utime.tv_sec) * 1000;
|
||||
ms += (end->ru_utime.tv_usec - start->ru_utime.tv_usec) / 1000;
|
||||
*/
|
||||
start_ms = start->tv_sec * 1000.0 + start->tv_nsec / (1000.0 * 1000);
|
||||
end_ms = end->tv_sec * 1000.0 + end->tv_nsec / (1000.0 * 1000);
|
||||
|
||||
ms += (end->ru_stime.tv_sec - start->ru_stime.tv_sec) * 1000;
|
||||
ms += (end->ru_stime.tv_usec - start->ru_stime.tv_usec) / 1000;
|
||||
|
||||
return ms;
|
||||
*ms = end_ms - start_ms;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cipher_perf_one(struct cipher_perf *cp, char *buf,
|
||||
@@ -98,26 +99,39 @@ static int cipher_perf_one(struct cipher_perf *cp, char *buf,
|
||||
|
||||
return r;
|
||||
}
|
||||
static long cipher_measure(struct cipher_perf *cp, char *buf,
|
||||
size_t buf_size, int encrypt)
|
||||
static int cipher_measure(struct cipher_perf *cp, char *buf,
|
||||
size_t buf_size, int encrypt, double *ms)
|
||||
{
|
||||
struct rusage rstart, rend;
|
||||
struct timespec start, end;
|
||||
int r;
|
||||
|
||||
if (getrusage(RUSAGE_SELF, &rstart) < 0)
|
||||
/*
|
||||
* Using getrusage would be better here but the precision
|
||||
* is not adequate, so better stick with CLOCK_MONOTONIC
|
||||
*/
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &start) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
r = cipher_perf_one(cp, buf, buf_size, encrypt);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (getrusage(RUSAGE_SELF, &rend) < 0)
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &end) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
return time_ms(&rstart, &rend);
|
||||
r = time_ms(&start, &end, ms);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (*ms < CIPHER_TIME_MIN_MS) {
|
||||
log_dbg("Measured cipher runtime (%1.6f) is too low.", *ms);
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static double speed_mbs(unsigned long bytes, unsigned long ms)
|
||||
static double speed_mbs(unsigned long bytes, double ms)
|
||||
{
|
||||
double speed = bytes, s = ms / 1000.;
|
||||
|
||||
@@ -127,32 +141,32 @@ static double speed_mbs(unsigned long bytes, unsigned long ms)
|
||||
static int cipher_perf(struct cipher_perf *cp,
|
||||
double *encryption_mbs, double *decryption_mbs)
|
||||
{
|
||||
long ms_enc, ms_dec, ms;
|
||||
int repeat_enc, repeat_dec;
|
||||
double ms_enc, ms_dec, ms;
|
||||
int r, repeat_enc, repeat_dec;
|
||||
void *buf = NULL;
|
||||
|
||||
if (posix_memalign(&buf, crypt_getpagesize(), cp->buffer_size))
|
||||
return -ENOMEM;
|
||||
|
||||
ms_enc = 0;
|
||||
ms_enc = 0.0;
|
||||
repeat_enc = 1;
|
||||
while (ms_enc < 1000) {
|
||||
ms = cipher_measure(cp, buf, cp->buffer_size, 1);
|
||||
if (ms < 0) {
|
||||
while (ms_enc < 1000.0) {
|
||||
r = cipher_measure(cp, buf, cp->buffer_size, 1, &ms);
|
||||
if (r < 0) {
|
||||
free(buf);
|
||||
return (int)ms;
|
||||
return r;
|
||||
}
|
||||
ms_enc += ms;
|
||||
repeat_enc++;
|
||||
}
|
||||
|
||||
ms_dec = 0;
|
||||
ms_dec = 0.0;
|
||||
repeat_dec = 1;
|
||||
while (ms_dec < 1000) {
|
||||
ms = cipher_measure(cp, buf, cp->buffer_size, 0);
|
||||
if (ms < 0) {
|
||||
while (ms_dec < 1000.0) {
|
||||
r = cipher_measure(cp, buf, cp->buffer_size, 0, &ms);
|
||||
if (r < 0) {
|
||||
free(buf);
|
||||
return (int)ms;
|
||||
return r;
|
||||
}
|
||||
ms_dec += ms;
|
||||
repeat_dec++;
|
||||
|
||||
Reference in New Issue
Block a user