1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
|
#include "resources.h"
#include <atomic>
#include <cassert>
#include <cmath>
#include <unistd.h> // for sysconf
#include <aocommon/logger.h>
using aocommon::Logger;
namespace wsclean {
namespace {
double RoundOneDecimal(double value) { return std::round(value * 10.0) / 10.0; }
} // namespace
Resources Resources::GetCombined(size_t num_combined) const {
assert(num_combined != 0);
const size_t n_cpus = n_cpus_ * num_combined;
const int64_t memory = memory_ * num_combined;
return Resources(n_cpus, memory);
}
Resources Resources::GetPart(size_t part_size) const {
assert(part_size != 0);
const size_t n_cpus =
std::max<size_t>(1, (n_cpus_ + part_size - 1) / part_size);
const int64_t memory = memory_ / part_size;
return Resources(n_cpus, memory);
}
int64_t GetAvailableMemory(double memory_fraction, double abs_memory_limit) {
assert(memory_fraction > 0.0 && memory_fraction <= 1.0);
// During the first run of this function, some information is reported
// This needs to be thread safe because gridders can call this function in
// parallel.
const int64_t gb = 1024.0 * 1024.0 * 1024.0;
static std::atomic<bool> isFirst(true);
const bool print_output = isFirst.exchange(false);
const long page_count = sysconf(_SC_PHYS_PAGES);
const long page_size = sysconf(_SC_PAGE_SIZE);
int64_t memory = (int64_t)page_count * (int64_t)page_size;
const double memory_size_in_gb = (double)memory / gb;
if (memory_fraction == 1.0 && abs_memory_limit == 0.0) {
if (print_output) {
Logger::Info << "Detected " << RoundOneDecimal(memory_size_in_gb)
<< " GB of system memory, usage not limited.\n";
}
} else {
if (print_output) {
double limit_in_gb = memory_size_in_gb * memory_fraction;
if (abs_memory_limit != 0.0)
limit_in_gb = std::min(limit_in_gb, abs_memory_limit);
Logger::Info << "Detected " << RoundOneDecimal(memory_size_in_gb)
<< " GB of system memory, usage limited to "
<< RoundOneDecimal(limit_in_gb)
<< " GB (frac=" << RoundOneDecimal(memory_fraction * 100.0)
<< "%, ";
if (abs_memory_limit == 0.0)
Logger::Info << "no abs limit)\n";
else
Logger::Info << "abs limit=" << RoundOneDecimal(abs_memory_limit)
<< "GB)\n";
}
memory = int64_t((double)page_count * (double)page_size * memory_fraction);
if (abs_memory_limit != 0.0)
memory = std::min<int64_t>(double(gb) * abs_memory_limit, memory);
}
return memory;
}
} // namespace wsclean
|