mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-08 15:54:57 +01:00
adjust sftest.cc to be more usable as a write-bandwidth tester
This commit is contained in:
parent
85f9615c26
commit
849da554a7
1 changed files with 84 additions and 11 deletions
|
|
@ -13,6 +13,8 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <float.h>
|
||||||
|
|
||||||
#include <glibmm/miscutils.h>
|
#include <glibmm/miscutils.h>
|
||||||
|
|
||||||
|
|
@ -21,6 +23,13 @@ using namespace std;
|
||||||
SF_INFO format_info;
|
SF_INFO format_info;
|
||||||
float* data = 0;
|
float* data = 0;
|
||||||
bool with_sync = false;
|
bool with_sync = false;
|
||||||
|
bool keep_writing = true;
|
||||||
|
|
||||||
|
void
|
||||||
|
signal_handler (int)
|
||||||
|
{
|
||||||
|
keep_writing = false;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
write_one (SNDFILE* sf, uint32_t nframes)
|
write_one (SNDFILE* sf, uint32_t nframes)
|
||||||
|
|
@ -39,7 +48,13 @@ write_one (SNDFILE* sf, uint32_t nframes)
|
||||||
void
|
void
|
||||||
usage ()
|
usage ()
|
||||||
{
|
{
|
||||||
cout << "sftest [ -f HEADER-FORMAT ] [ -F DATA-FORMAT ] [ -r SAMPLERATE ] [ -n NFILES ] [ -b BLOCKSIZE ] [ -s ]" << endl;
|
cout << "sftest [ -f HEADER-FORMAT ] [ -F DATA-FORMAT ] [ -r SAMPLERATE ] [ -n NFILES ] [ -b BLOCKSIZE ] [ -s ]";
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
cout << " [ -D ]";
|
||||||
|
#endif
|
||||||
|
cout << endl;
|
||||||
|
|
||||||
cout << "\tHEADER-FORMAT is one of:" << endl
|
cout << "\tHEADER-FORMAT is one of:" << endl
|
||||||
<< "\t\tWAV" << endl
|
<< "\t\tWAV" << endl
|
||||||
<< "\t\tCAF" << endl
|
<< "\t\tCAF" << endl
|
||||||
|
|
@ -56,14 +71,24 @@ main (int argc, char* argv[])
|
||||||
{
|
{
|
||||||
vector<SNDFILE*> sndfiles;
|
vector<SNDFILE*> sndfiles;
|
||||||
uint32_t sample_size;
|
uint32_t sample_size;
|
||||||
char optstring[] = "f:r:F:n:c:b:sD";
|
char optstring[] = "f:r:F:n:c:b:sd:qS:"
|
||||||
int channels, samplerate;
|
#ifdef __APPLE__
|
||||||
|
"D"
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
int channels = 1;
|
||||||
|
int samplerate = 48000;
|
||||||
char const *suffix = ".wav";
|
char const *suffix = ".wav";
|
||||||
char const *header_format = "wav";
|
char const *header_format = "wav";
|
||||||
char const *data_format = "float";
|
char const *data_format = "float";
|
||||||
|
size_t filesize = 10 * 1048576;
|
||||||
uint32_t block_size = 64 * 1024;
|
uint32_t block_size = 64 * 1024;
|
||||||
uint32_t nfiles = 100;
|
uint32_t nfiles = 100;
|
||||||
|
string dirname = "/tmp";
|
||||||
|
bool quiet = false;
|
||||||
|
#ifdef __APPLE__
|
||||||
bool direct = false;
|
bool direct = false;
|
||||||
|
#endif
|
||||||
const struct option longopts[] = {
|
const struct option longopts[] = {
|
||||||
{ "header-format", 1, 0, 'f' },
|
{ "header-format", 1, 0, 'f' },
|
||||||
{ "data-format", 1, 0, 'F' },
|
{ "data-format", 1, 0, 'F' },
|
||||||
|
|
@ -72,7 +97,12 @@ main (int argc, char* argv[])
|
||||||
{ "blocksize", 1, 0, 'b' },
|
{ "blocksize", 1, 0, 'b' },
|
||||||
{ "channels", 1, 0, 'c' },
|
{ "channels", 1, 0, 'c' },
|
||||||
{ "sync", 0, 0, 's' },
|
{ "sync", 0, 0, 's' },
|
||||||
|
{ "dirname", 1, 0, 'd' },
|
||||||
|
{ "quiet", 0, 0, 'q' },
|
||||||
|
{ "filesize", 1, 0, 'S' },
|
||||||
|
#ifdef __APPLE__
|
||||||
{ "direct", 0, 0, 'D' },
|
{ "direct", 0, 0, 'D' },
|
||||||
|
#endif
|
||||||
{ 0, 0, 0, 0 }
|
{ 0, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -110,9 +140,20 @@ main (int argc, char* argv[])
|
||||||
case 's':
|
case 's':
|
||||||
with_sync = true;
|
with_sync = true;
|
||||||
break;
|
break;
|
||||||
|
case 'S':
|
||||||
|
filesize = atoi (optarg);
|
||||||
|
break;
|
||||||
|
#ifdef __APPLE__
|
||||||
case 'D':
|
case 'D':
|
||||||
direct = true;
|
direct = true;
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
case 'd':
|
||||||
|
dirname = optarg;
|
||||||
|
break;
|
||||||
|
case 'q':
|
||||||
|
quiet = true;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
usage ();
|
usage ();
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -161,8 +202,11 @@ main (int argc, char* argv[])
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char tmpdirname[] = "sftest-XXXXXX";
|
string tmpdirname = Glib::build_filename (dirname, "sftest");
|
||||||
g_mkdtemp (tmpdirname);
|
if (g_mkdir_with_parents (tmpdirname.c_str(), 0755)) {
|
||||||
|
cerr << "Cannot create output directory\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
for (uint32_t n = 0; n < nfiles; ++n) {
|
for (uint32_t n = 0; n < nfiles; ++n) {
|
||||||
SNDFILE* sf;
|
SNDFILE* sf;
|
||||||
|
|
@ -202,13 +246,26 @@ main (int argc, char* argv[])
|
||||||
sndfiles.push_back (sf);
|
sndfiles.push_back (sf);
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << nfiles << " files are in " << tmpdirname << " all used " << (direct ? "without" : "with") << " OS buffer cache" << endl;
|
if (!quiet) {
|
||||||
cout << "Format is " << suffix << ' ' << channels << " channel" << (channels > 1 ? "s" : "") << " written in chunks of " << block_size << " frames, synced ? " << (with_sync ? "yes" : "no") << endl;
|
cout << nfiles << " files are in " << tmpdirname;
|
||||||
|
#ifdef __APPLE__
|
||||||
|
cout << " all used " << (direct ? "without" : "with") << " OS buffer cache";
|
||||||
|
#endif
|
||||||
|
cout << endl;
|
||||||
|
cout << "Format is " << suffix << ' ' << channels << " channel" << (channels > 1 ? "s" : "") << " written in chunks of " << block_size << " frames, synced ? " << (with_sync ? "yes" : "no") << endl;
|
||||||
|
}
|
||||||
|
|
||||||
data = new float[block_size*channels];
|
data = new float[block_size*channels];
|
||||||
uint64_t written = 0;
|
uint64_t written = 0;
|
||||||
|
|
||||||
while (true) {
|
signal (SIGINT, signal_handler);
|
||||||
|
signal (SIGSTOP, signal_handler);
|
||||||
|
|
||||||
|
|
||||||
|
double max_bandwidth = 0;
|
||||||
|
double min_bandwidth = DBL_MAX;
|
||||||
|
|
||||||
|
while (keep_writing && written < filesize) {
|
||||||
gint64 before;
|
gint64 before;
|
||||||
before = g_get_monotonic_time();
|
before = g_get_monotonic_time();
|
||||||
for (vector<SNDFILE*>::iterator s = sndfiles.begin(); s != sndfiles.end(); ++s) {
|
for (vector<SNDFILE*>::iterator s = sndfiles.begin(); s != sndfiles.end(); ++s) {
|
||||||
|
|
@ -225,7 +282,23 @@ main (int argc, char* argv[])
|
||||||
stringstream ds;
|
stringstream ds;
|
||||||
ds << setprecision (1) << data_minutes;
|
ds << setprecision (1) << data_minutes;
|
||||||
|
|
||||||
cout << "BW @ " << written << " frames (" << ds.str() << " minutes) = " << (bandwidth/1048576.0) << " MB/sec " << bandwidth / data_rate << " x faster than necessary " << endl;
|
max_bandwidth = max (max_bandwidth, bandwidth);
|
||||||
|
min_bandwidth = min (min_bandwidth, bandwidth);
|
||||||
|
|
||||||
|
if (!quiet) {
|
||||||
|
cout << "BW @ " << written << " frames (" << ds.str() << " minutes) = " << (bandwidth/1048576.0) << " MB/sec " << bandwidth / data_rate << " x faster than necessary " << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << "Max bandwidth = " << max_bandwidth / 1048576.0 << " MB/sec" << endl;
|
||||||
|
cout << "Min bandwidth = " << min_bandwidth / 1048576.0 << " MB/sec" << endl;
|
||||||
|
|
||||||
|
if (!quiet) {
|
||||||
|
cout << "Closing files ...\n";
|
||||||
|
for (vector<SNDFILE*>::iterator s = sndfiles.begin(); s != sndfiles.end(); ++s) {
|
||||||
|
sf_close (*s);
|
||||||
|
}
|
||||||
|
cout << "Done.\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue