KASM-6788 use thread and future instead of openmp for image encoding

This commit is contained in:
ryan.kuba 2025-02-11 09:51:18 -05:00 committed by El
parent e647af5e28
commit 0017991a55
No known key found for this signature in database
GPG Key ID: EB3F4C9EA29CDE59
2 changed files with 34 additions and 10 deletions

View File

@ -22,6 +22,12 @@
#include <omp.h> #include <omp.h>
#include <stdlib.h> #include <stdlib.h>
#include <thread>
#include <future>
#include <vector>
#include <atomic>
#include <rfb/cpuid.h> #include <rfb/cpuid.h>
#include <rfb/EncCache.h> #include <rfb/EncCache.h>
#include <rfb/EncodeManager.h> #include <rfb/EncodeManager.h>
@ -210,6 +216,7 @@ EncodeManager::EncodeManager(SConnection* conn_, EncCache *encCache_) : conn(con
dynamicQualityMin = Server::dynamicQualityMin; dynamicQualityMin = Server::dynamicQualityMin;
dynamicQualityOff = Server::dynamicQualityMax - Server::dynamicQualityMin; dynamicQualityOff = Server::dynamicQualityMax - Server::dynamicQualityMin;
} }
std::atomic<bool> webpTookTooLong{false};
} }
EncodeManager::~EncodeManager() EncodeManager::~EncodeManager()
@ -886,8 +893,7 @@ void EncodeManager::checkWebpFallback(const struct timeval *start) {
unsigned us; unsigned us;
us = msSince(start) * 1024; us = msSince(start) * 1024;
if (us > webpFallbackUs) if (us > webpFallbackUs)
#pragma omp atomic webpTookTooLong = true;
webpTookTooLong |= true;
} }
} }
@ -1130,8 +1136,10 @@ void EncodeManager::writeRects(const Region& changed, const PixelBuffer* pb,
std::vector<uint32_t> ms; std::vector<uint32_t> ms;
uint32_t i; uint32_t i;
if (rfb::Server::rectThreads > 0) int num_threads = std::thread::hardware_concurrency();
omp_set_num_threads(rfb::Server::rectThreads); if (rfb::Server::rectThreads > 0) {
num_threads = rfb::Server::rectThreads;
}
webpTookTooLong = false; webpTookTooLong = false;
changed.get_rects(&rects); changed.get_rects(&rects);
@ -1249,12 +1257,27 @@ void EncodeManager::writeRects(const Region& changed, const PixelBuffer* pb,
} }
scalingTime = msSince(&scalestart); scalingTime = msSince(&scalestart);
#pragma omp parallel for schedule(dynamic, 1) std::vector<std::future<void>> futures;
futures.reserve(subrects.size());
for (i = 0; i < subrects.size(); ++i) { for (i = 0; i < subrects.size(); ++i) {
encoderTypes[i] = getEncoderType(subrects[i], pb, &palettes[i], compresseds[i], Rect subrect = subrects[i];
&isWebp[i], &fromCache[i], const PixelBuffer* current_pb = pb;
scaledpb, scaledrects[i], ms[i]); uint8_t* current_encoderTypes = &encoderTypes[i];
checkWebpFallback(start); uint8_t* current_fromCache = &fromCache[i];
const PixelBuffer* current_scaledpb = scaledpb;
Rect current_scaledrect = scaledrects[i];
uint32_t* current_ms = &ms[i];
const struct timeval* current_start = start;
auto task = [this, subrect, current_pb, &palettes, &compresseds, &isWebp, current_encoderTypes, current_fromCache, current_scaledpb, current_scaledrect, current_ms, current_start, i]() {
*current_encoderTypes = getEncoderType(subrect, current_pb, &palettes[i], compresseds[i],
&isWebp[i], current_fromCache,
current_scaledpb, current_scaledrect, *current_ms);
checkWebpFallback(current_start);
};
futures.push_back(std::async(std::launch::async, task));
}
for (auto& future : futures) {
future.get();
} }
for (i = 0; i < subrects.size(); ++i) { for (i = 0; i < subrects.size(); ++i) {

View File

@ -32,6 +32,7 @@
#include <rfb/util.h> #include <rfb/util.h>
#include <stdint.h> #include <stdint.h>
#include <atomic>
#include <sys/time.h> #include <sys/time.h>
namespace rfb { namespace rfb {
@ -199,7 +200,7 @@ namespace rfb {
size_t curMaxUpdateSize; size_t curMaxUpdateSize;
unsigned webpFallbackUs; unsigned webpFallbackUs;
unsigned webpBenchResult; unsigned webpBenchResult;
bool webpTookTooLong; std::atomic<bool> webpTookTooLong;
unsigned encodingTime; unsigned encodingTime;
unsigned maxEncodingTime, framesSinceEncPrint; unsigned maxEncodingTime, framesSinceEncPrint;
unsigned scalingTime; unsigned scalingTime;