Alternative Upload geometry data in parallel to multiple GPUs using the "Multi-Device" #107552
|
@ -4,6 +4,15 @@
|
|||
#ifndef __UTIL_PROGRESS_H__
|
||||
#define __UTIL_PROGRESS_H__
|
||||
|
||||
//#define USE_SPINLOCK
|
||||
#ifdef USE_SPINLOCK
|
||||
#define MUTEX SpinLock
|
||||
#define SCOPED_LOCK(mutex) ScopedSpinLock scopedspinlock(mutex)
|
||||
#else
|
||||
#define MUTEX thread_mutex
|
||||
#define SCOPED_LOCK(mutex) thread_scoped_lock scopedlock(mutex)
|
||||
#endif
|
||||
|
||||
/* Progress
|
||||
*
|
||||
* Simple class to communicate progress status messages, timing information,
|
||||
|
@ -19,6 +28,45 @@
|
|||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
class SpinLock {
|
||||
public:
|
||||
SpinLock()
|
||||
{
|
||||
update_status = true;
|
||||
};
|
||||
|
||||
void lock()
|
||||
{
|
||||
// Busy wait until update status is true
|
||||
bool can_update = true;
|
||||
while (!update_status.compare_exchange_weak(can_update, false)) {
|
||||
};
|
||||
};
|
||||
|
||||
void unlock()
|
||||
{
|
||||
update_status = true;
|
||||
};
|
||||
|
||||
private:
|
||||
std::atomic<bool> update_status;
|
||||
};
|
||||
|
||||
class ScopedSpinLock {
|
||||
public:
|
||||
ScopedSpinLock(SpinLock &spinlock) : spinlock_(spinlock)
|
||||
{
|
||||
spinlock_.lock();
|
||||
};
|
||||
|
||||
~ScopedSpinLock()
|
||||
{
|
||||
spinlock_.unlock();
|
||||
}
|
||||
private:
|
||||
SpinLock &spinlock_;
|
||||
};
|
||||
|
||||
class Progress {
|
||||
public:
|
||||
using callback_type = function<void()>;
|
||||
|
@ -45,8 +93,8 @@ class Progress {
|
|||
error_message = "";
|
||||
cancel_cb = function_null;
|
||||
updates = true;
|
||||
update_call = true;
|
||||
update_status = true;
|
||||
// update_call = true;
|
||||
// update_status = true;
|
||||
}
|
||||
|
||||
Progress(Progress &progress)
|
||||
|
@ -56,13 +104,14 @@ class Progress {
|
|||
|
||||
Progress &operator=(Progress &progress)
|
||||
{
|
||||
update_progress([this, &progress]() {
|
||||
SCOPED_LOCK(progress_mutex);
|
||||
//update_progress([this, &progress]() {
|
||||
progress.get_status(status, substatus);
|
||||
|
||||
pixel_samples = progress.pixel_samples;
|
||||
total_pixel_samples = progress.total_pixel_samples;
|
||||
current_tile_sample = progress.get_current_sample();
|
||||
});
|
||||
//});
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
@ -97,11 +146,11 @@ class Progress {
|
|||
/* cancel */
|
||||
void set_cancel(const string &cancel_message_)
|
||||
{
|
||||
update_progress([this, cancel_message_]() {
|
||||
cancel_message = cancel_message_;
|
||||
cancel = true;
|
||||
update_status = true;
|
||||
});
|
||||
SCOPED_LOCK(progress_mutex);
|
||||
//update_progress([this, cancel_message_]() {
|
||||
cancel_message = cancel_message_;
|
||||
cancel = true;
|
||||
//});
|
||||
}
|
||||
|
||||
bool get_cancel() const
|
||||
|
@ -119,11 +168,12 @@ class Progress {
|
|||
|
||||
string get_cancel_message() //const
|
||||
{
|
||||
string msg;
|
||||
update_progress([this, &msg]() {
|
||||
msg = cancel_message;
|
||||
});
|
||||
return msg;
|
||||
SCOPED_LOCK(progress_mutex);
|
||||
//string msg;
|
||||
//update_progress([this, &msg]() {
|
||||
//msg = cancel_message;
|
||||
//});
|
||||
return cancel_message;
|
||||
}
|
||||
|
||||
void set_cancel_callback(function<void()> function)
|
||||
|
@ -134,13 +184,14 @@ class Progress {
|
|||
/* error */
|
||||
void set_error(const string &error_message_)
|
||||
{
|
||||
update_progress([this, error_message_]() {
|
||||
error_message = error_message_;
|
||||
error = true;
|
||||
/* If error happens we also stop rendering. */
|
||||
cancel_message = error_message_;
|
||||
cancel = true;
|
||||
});
|
||||
SCOPED_LOCK(progress_mutex);
|
||||
//update_progress([this, error_message_]() {
|
||||
error_message = error_message_;
|
||||
error = true;
|
||||
/* If error happens we also stop rendering. */
|
||||
cancel_message = error_message_;
|
||||
cancel = true;
|
||||
//});
|
||||
}
|
||||
|
||||
bool get_error() const
|
||||
|
@ -150,34 +201,39 @@ class Progress {
|
|||
|
||||
string get_error_message() // const
|
||||
{
|
||||
string msg;
|
||||
update_progress([this, &msg]() {
|
||||
msg = error_message;
|
||||
update_status = true;
|
||||
});
|
||||
return msg;
|
||||
SCOPED_LOCK(progress_mutex);
|
||||
//string msg;
|
||||
//update_progress([this, &msg]() {
|
||||
//msg = error_message;
|
||||
//});
|
||||
return error_message;
|
||||
}
|
||||
|
||||
/* tile and timing information */
|
||||
|
||||
void set_start_time()
|
||||
{
|
||||
update_progress([this]() {
|
||||
start_time = time_dt();
|
||||
end_time = 0.0;
|
||||
});
|
||||
SCOPED_LOCK(progress_mutex);
|
||||
//update_progress([this]() {
|
||||
start_time = time_dt();
|
||||
end_time = 0.0;
|
||||
//});
|
||||
}
|
||||
|
||||
void set_render_start_time()
|
||||
{
|
||||
update_progress([this]() {
|
||||
render_start_time = time_dt();
|
||||
});
|
||||
SCOPED_LOCK(progress_mutex);
|
||||
//update_progress([this]() {
|
||||
render_start_time = time_dt();
|
||||
//});
|
||||
}
|
||||
|
||||
void set_time_limit(double time_limit_)
|
||||
{
|
||||
update_progress([this, time_limit_]() { time_limit = time_limit_; });
|
||||
SCOPED_LOCK(progress_mutex);
|
||||
//update_progress([this, time_limit_]() {
|
||||
time_limit = time_limit_;
|
||||
//});
|
||||
}
|
||||
|
||||
void add_skip_time(const scoped_timer &start_timer, bool only_render)
|
||||
|
@ -192,13 +248,14 @@ class Progress {
|
|||
|
||||
void get_time(double &total_time_, double &render_time_) //const
|
||||
{
|
||||
update_progress([this, &total_time_, &render_time_](){
|
||||
SCOPED_LOCK(progress_mutex);
|
||||
//update_progress([this, &total_time_, &render_time_](){
|
||||
double et = end_time;
|
||||
double time = (et > 0) ? et : time_dt();
|
||||
|
||||
total_time_ = time - start_time;
|
||||
render_time_ = time - render_start_time;
|
||||
});
|
||||
//});
|
||||
}
|
||||
|
||||
void set_end_time()
|
||||
|
@ -216,15 +273,17 @@ class Progress {
|
|||
|
||||
void set_total_pixel_samples(uint64_t total_pixel_samples_)
|
||||
{
|
||||
update_progress([this, total_pixel_samples_](){
|
||||
SCOPED_LOCK(progress_mutex);
|
||||
//update_progress([this, total_pixel_samples_](){
|
||||
total_pixel_samples = total_pixel_samples_;
|
||||
});
|
||||
//});
|
||||
}
|
||||
|
||||
double get_progress() //const
|
||||
{
|
||||
SCOPED_LOCK(progress_mutex);
|
||||
double value = 0.0;
|
||||
update_progress([this, &value]() {
|
||||
//update_progress([this, &value]() {
|
||||
if (pixel_samples > 0) {
|
||||
double progress_percent = (double)pixel_samples / (double)total_pixel_samples;
|
||||
if (time_limit != 0.0) {
|
||||
|
@ -233,17 +292,18 @@ class Progress {
|
|||
}
|
||||
value = min(1.0, progress_percent);
|
||||
}
|
||||
});
|
||||
//});
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void add_samples(uint64_t pixel_samples_, int tile_sample)
|
||||
{
|
||||
update_progress([this, pixel_samples_, tile_sample]() {
|
||||
SCOPED_LOCK(progress_mutex);
|
||||
//update_progress([this, pixel_samples_, tile_sample]() {
|
||||
pixel_samples += pixel_samples_;
|
||||
current_tile_sample = tile_sample;
|
||||
});
|
||||
//});
|
||||
}
|
||||
|
||||
void add_samples_update(uint64_t pixel_samples_, int tile_sample)
|
||||
|
@ -254,55 +314,59 @@ class Progress {
|
|||
|
||||
void add_finished_tile(bool denoised)
|
||||
{
|
||||
update_progress([this, denoised]() {
|
||||
SCOPED_LOCK(progress_mutex);
|
||||
//update_progress([this, denoised]() {
|
||||
if (denoised) {
|
||||
denoised_tiles++;
|
||||
}
|
||||
else {
|
||||
rendered_tiles++;
|
||||
}
|
||||
});
|
||||
//});
|
||||
}
|
||||
|
||||
int get_current_sample() //const
|
||||
{
|
||||
int sample;
|
||||
update_progress([this, &sample]() {
|
||||
SCOPED_LOCK(progress_mutex);
|
||||
//int sample;
|
||||
//update_progress([this, &sample]() {
|
||||
/* Note that the value here always belongs to the last tile that updated,
|
||||
* so it's only useful if there is only one active tile. */
|
||||
sample = current_tile_sample;
|
||||
});
|
||||
return sample;
|
||||
//sample = current_tile_sample;
|
||||
//});
|
||||
return current_tile_sample;
|
||||
}
|
||||
|
||||
int get_rendered_tiles() //const
|
||||
{
|
||||
int tiles;
|
||||
update_progress([this, &tiles]() {
|
||||
tiles = rendered_tiles;
|
||||
});
|
||||
return tiles;
|
||||
SCOPED_LOCK(progress_mutex);
|
||||
//int tiles;
|
||||
//update_progress([this, &tiles]() {
|
||||
// tiles = rendered_tiles;
|
||||
//});
|
||||
return rendered_tiles;
|
||||
}
|
||||
|
||||
int get_denoised_tiles() //const
|
||||
{
|
||||
int denoised;
|
||||
update_progress([this, & denoised]() {
|
||||
denoised = denoised_tiles;
|
||||
});
|
||||
return denoised;
|
||||
SCOPED_LOCK(progress_mutex);
|
||||
//int denoised;
|
||||
//update_progress([this, & denoised]() {
|
||||
// denoised = denoised_tiles;
|
||||
//});
|
||||
return denoised_tiles;
|
||||
}
|
||||
|
||||
/* status messages */
|
||||
|
||||
void set_status(const string &status_, const string &substatus_ = "")
|
||||
{
|
||||
if(updates)
|
||||
{
|
||||
update_progress([this, status_, substatus_]() {
|
||||
if(updates) {
|
||||
SCOPED_LOCK(progress_mutex);
|
||||
//update_progress([this, status_, substatus_]() {
|
||||
status = status_;
|
||||
substatus = substatus_;
|
||||
});
|
||||
//});
|
||||
}
|
||||
|
||||
set_update();
|
||||
|
@ -310,11 +374,11 @@ class Progress {
|
|||
|
||||
void set_substatus(const string &substatus_)
|
||||
{
|
||||
if(updates)
|
||||
{
|
||||
update_progress([this, substatus_]() {
|
||||
if(updates) {
|
||||
SCOPED_LOCK(progress_mutex);
|
||||
//update_progress([this, substatus_]() {
|
||||
substatus = substatus_;
|
||||
});
|
||||
//});
|
||||
}
|
||||
|
||||
set_update();
|
||||
|
@ -323,10 +387,11 @@ class Progress {
|
|||
void set_sync_status(const string &status_, const string &substatus_ = "")
|
||||
{
|
||||
if(updates) {
|
||||
update_progress([this, status_, substatus_]() {
|
||||
sync_status = status_;
|
||||
sync_substatus = substatus_;
|
||||
});
|
||||
SCOPED_LOCK(progress_mutex);
|
||||
//update_progress([this, status_, substatus_]() {
|
||||
sync_status = status_;
|
||||
sync_substatus = substatus_;
|
||||
//});
|
||||
}
|
||||
|
||||
set_update();
|
||||
|
@ -335,9 +400,10 @@ class Progress {
|
|||
void set_sync_substatus(const string &substatus_)
|
||||
{
|
||||
if(updates) {
|
||||
update_progress([this, substatus_]() {
|
||||
sync_substatus = substatus_;
|
||||
});
|
||||
SCOPED_LOCK(progress_mutex);
|
||||
//update_progress([this, substatus_]() {
|
||||
sync_substatus = substatus_;
|
||||
//});
|
||||
}
|
||||
|
||||
set_update();
|
||||
|
@ -345,7 +411,8 @@ class Progress {
|
|||
|
||||
void get_status(string &status_, string &substatus_) // const
|
||||
{
|
||||
update_progress([this, &status_, &substatus_]() {
|
||||
SCOPED_LOCK(progress_mutex);
|
||||
//update_progress([this, &status_, &substatus_]() {
|
||||
if (sync_status != "") {
|
||||
status_ = sync_status;
|
||||
substatus_ = sync_substatus;
|
||||
|
@ -354,7 +421,7 @@ class Progress {
|
|||
status_ = status;
|
||||
substatus_ = substatus;
|
||||
}
|
||||
});
|
||||
//});
|
||||
}
|
||||
|
||||
/* callback */
|
||||
|
@ -362,11 +429,12 @@ class Progress {
|
|||
void set_update()
|
||||
{
|
||||
if (updates && update_cb) {
|
||||
SCOPED_LOCK(update_mutex);
|
||||
// Busy wait until update status is true
|
||||
bool can_update = true;
|
||||
while(!update_call.compare_exchange_weak(can_update, false)) {};
|
||||
//bool can_update = true;
|
||||
//while(!update_call.compare_exchange_weak(can_update, false)) {};
|
||||
update_cb();
|
||||
update_call = true;
|
||||
//update_call = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -375,20 +443,20 @@ class Progress {
|
|||
update_cb = function;
|
||||
}
|
||||
|
||||
void update_progress(callback_type cb)
|
||||
{
|
||||
// Busy wait until update status is true
|
||||
bool can_update = true;
|
||||
while(!update_status.compare_exchange_weak(can_update, false)) {};
|
||||
if (cb) {
|
||||
cb();
|
||||
}
|
||||
update_status = true;
|
||||
}
|
||||
// void update_progress(callback_type cb)
|
||||
// {
|
||||
// // Busy wait until update status is true
|
||||
// bool can_update = true;
|
||||
// while(!update_status.compare_exchange_weak(can_update, false)) {};
|
||||
// if (cb) {
|
||||
// cb();
|
||||
// }
|
||||
// update_status = true;
|
||||
// }
|
||||
|
||||
protected:
|
||||
//mutable thread_mutex progress_mutex;
|
||||
//mutable thread_mutex update_mutex;
|
||||
mutable MUTEX progress_mutex;
|
||||
mutable MUTEX update_mutex;
|
||||
function<void()> update_cb;
|
||||
function<void()> cancel_cb;
|
||||
|
||||
|
@ -409,9 +477,6 @@ class Progress {
|
|||
/* End time written when render is done, so it doesn't keep increasing on redraws. */
|
||||
double end_time;
|
||||
|
||||
std::atomic<bool> update_call;
|
||||
std::atomic<bool> update_status;
|
||||
|
||||
string status;
|
||||
string substatus;
|
||||
|
||||
|
|
Loading…
Reference in New Issue