@@ -20,165 +20,166 @@ using namespace video;
2020
2121class ThreadPool
2222{
23- using task_t = std::function<void ()>;
23+ using task_t = std::function<void ()>;
2424public:
25- ThreadPool (size_t workers = std::thread::hardware_concurrency())
26- {
27- for (size_t i = 0 ; i < workers; i++)
28- {
29- m_workers.emplace_back ([this ] {
30- task_t task;
31-
32- while (1 )
33- {
34- {
35- std::unique_lock<std::mutex> lock (m_queueLock);
36- m_taskAvailable.wait (lock, [this ] { return !m_tasks.empty () || m_shouldStop; });
37-
38- if (m_shouldStop && m_tasks.empty ()) {
39- return ;
40- }
41-
42- task = std::move (m_tasks.front ());
43- m_tasks.pop ();
44- }
45-
46- task ();
47- }
48- });
49- }
50- }
51-
52- ~ThreadPool ()
53- {
54- m_shouldStop = true ;
55- m_taskAvailable.notify_all ();
56-
57- for (auto & worker : m_workers)
58- {
59- worker.join ();
60- }
61- }
62-
63- void enqueue (task_t task)
64- {
65- {
66- std::lock_guard<std::mutex> lock (m_queueLock);
67- m_tasks.emplace (std::move (task));
68- }
69- m_taskAvailable.notify_one ();
70- }
71- private:
72- std::mutex m_queueLock;
73- std::condition_variable m_taskAvailable;
74- std::vector<std::thread> m_workers;
75- std::queue<task_t > m_tasks;
76- std::atomic<bool > m_shouldStop = false ;
25+ ThreadPool (size_t workers = std::thread::hardware_concurrency())
26+ {
27+ for (size_t i = 0 ; i < workers; i++)
28+ {
29+ m_workers.emplace_back ([this ] {
30+ task_t task;
31+
32+ while (1 )
33+ {
34+ {
35+ std::unique_lock<std::mutex> lock (m_queueLock);
36+ m_taskAvailable.wait (lock, [this ] { return !m_tasks.empty () || m_shouldStop; });
37+
38+ if (m_shouldStop && m_tasks.empty ()) {
39+ return ;
40+ }
41+
42+ task = std::move (m_tasks.front ());
43+ m_tasks.pop ();
44+ }
45+
46+ task ();
47+ }
48+ });
49+ }
50+ }
51+
52+ ~ThreadPool ()
53+ {
54+ m_shouldStop = true ;
55+ m_taskAvailable.notify_all ();
56+
57+ for (auto & worker : m_workers)
58+ {
59+ worker.join ();
60+ }
61+ }
62+
63+ void enqueue (task_t task)
64+ {
65+ {
66+ std::lock_guard<std::mutex> lock (m_queueLock);
67+ m_tasks.emplace (std::move (task));
68+ }
69+ m_taskAvailable.notify_one ();
70+ }
71+ private:
72+ std::mutex m_queueLock;
73+ std::condition_variable m_taskAvailable;
74+ std::vector<std::thread> m_workers;
75+ std::queue<task_t > m_tasks;
76+ std::atomic<bool > m_shouldStop = false ;
7777};
7878
7979class JpegLoaderApp final : public application_templates::MonoAssetManagerAndBuiltinResourceApplication
8080{
81- using clock_t = std::chrono::steady_clock;
82- using clock_resolution_t = std::chrono::milliseconds;
83- using base_t = application_templates::MonoAssetManagerAndBuiltinResourceApplication;
84- public:
85- using base_t ::base_t ;
86-
87- inline bool onAppInitialized (smart_refctd_ptr<ISystem>&& system) override
88- {
89- argparse::ArgumentParser program (" Color Space" );
90-
91- program.add_argument <std::string>(" --directory" )
92- .required ()
93- .help (" Path to a directory where all JPEG files are stored (not recursive)" );
94-
95- program.add_argument <std::string>(" --output" )
96- .default_value (" output.json" )
97- .help (" Path to the file where the benchmark result will be stored" );
98-
99- try
100- {
101- program.parse_args ({ argv.data (), argv.data () + argv.size () });
102- }
103- catch (const std::exception& err)
104- {
105- std::cerr << err.what () << std::endl << program; // NOTE: std::cerr because logger isn't initialized yet
106- return false ;
107- }
108-
109- if (!base_t::onAppInitialized (std::move (system)))
110- return false ;
111-
112- options.directory = program.get <std::string>(" --directory" );
113- options.outputFile = program.get <std::string>(" --output" );
114-
115- // check if directory exists
116- if (!std::filesystem::exists (options.directory ))
117- {
118- logFail (" Provided directory doesn't exist" );
119- return false ;
120- }
121-
122- auto start = clock_t::now ();
123- std::vector<std::string> files;
124-
125- {
126- ThreadPool tp;
127-
128- constexpr auto cachingFlags = static_cast <IAssetLoader::E_CACHING_FLAGS>(IAssetLoader::ECF_DONT_CACHE_REFERENCES & IAssetLoader::ECF_DONT_CACHE_TOP_LEVEL);
129- const IAssetLoader::SAssetLoadParams loadParams (0ull , nullptr , cachingFlags, IAssetLoader::ELPF_NONE, m_logger.get ());
130-
131- for (auto & item : std::filesystem::directory_iterator (options.directory ))
132- {
133- auto & path = item.path ();
134- if (path.has_extension () && path.extension () == " .jpg" )
135- {
136- files.emplace_back (std::move (path.generic_string ()));
137- tp.enqueue ([=] {
138- m_logger->log (" Loading %S" , ILogger::ELL_INFO, path.c_str ());
139- m_assetMgr->getAsset (path.generic_string (), loadParams);
140- });
141- }
142- }
143- }
144-
145- auto stop = clock_t::now ();
146- auto time = std::chrono::duration_cast<clock_resolution_t >(stop - start).count ();
147-
148- m_logger->log (" Process took %llu ms" , ILogger::ELL_INFO, time);
149-
150- // Dump data to JSON
151- json j;
152- j[" loaded_files" ] = files;
153- j[" duration_ms" ] = time;
154-
155- std::ofstream output (options.outputFile );
156- if (!output.good ())
157- {
158- logFail (" Failed to open %S" , options.outputFile );
159- return false ;
160- }
161-
162- output << j;
163-
164- return true ;
165- }
166-
167- inline bool keepRunning () override
168- {
169- return false ;
170- }
171-
172- inline void workLoopBody () override
173- {
174-
175- }
81+ using clock_t = std::chrono::steady_clock;
82+ using clock_resolution_t = std::chrono::milliseconds;
83+ using base_t = application_templates::MonoAssetManagerAndBuiltinResourceApplication;
84+ public:
85+ using base_t ::base_t ;
86+
87+ inline bool onAppInitialized (smart_refctd_ptr<ISystem>&& system) override
88+ {
89+ argparse::ArgumentParser program (" Color Space" );
90+
91+ program.add_argument <std::string>(" --directory" )
92+ .required ()
93+ .help (" Path to a directory where all JPEG files are stored (not recursive)" );
94+
95+ program.add_argument <std::string>(" --output" )
96+ .default_value (" output.json" )
97+ .help (" Path to the file where the benchmark result will be stored" );
98+
99+ try
100+ {
101+ program.parse_args ({ argv.data (), argv.data () + argv.size () });
102+ }
103+ catch (const std::exception& err)
104+ {
105+ std::cerr << err.what () << std::endl << program; // NOTE: std::cerr because logger isn't initialized yet
106+ return false ;
107+ }
108+
109+ if (!base_t::onAppInitialized (std::move (system)))
110+ return false ;
111+
112+ options.directory = program.get <std::string>(" --directory" );
113+ options.outputFile = program.get <std::string>(" --output" );
114+
115+ // check if directory exists
116+ if (!std::filesystem::exists (options.directory ))
117+ {
118+ logFail (" Provided directory doesn't exist" );
119+ return false ;
120+ }
121+
122+ auto start = clock_t::now ();
123+ std::vector<std::string> files;
124+
125+ {
126+ ThreadPool tp;
127+
128+ constexpr auto cachingFlags = static_cast <IAssetLoader::E_CACHING_FLAGS>(IAssetLoader::ECF_DONT_CACHE_REFERENCES & IAssetLoader::ECF_DONT_CACHE_TOP_LEVEL);
129+ const IAssetLoader::SAssetLoadParams loadParams (0ull , nullptr , cachingFlags, IAssetLoader::ELPF_NONE, m_logger.get ());
130+
131+ for (auto & item : std::filesystem::directory_iterator (options.directory ))
132+ {
133+ auto & path = item.path ();
134+ if (path.has_extension () && path.extension () == " .jpg" )
135+ {
136+ files.emplace_back (std::move (path.generic_string ()));
137+ tp.enqueue ([=] {
138+ m_logger->log (" Loading %S" , ILogger::ELL_INFO, path.c_str ());
139+ m_assetMgr->getAsset (path.generic_string (), loadParams);
140+ });
141+ }
142+ }
143+ }
144+
145+ auto stop = clock_t::now ();
146+ auto time = std::chrono::duration_cast<clock_resolution_t >(stop - start).count ();
147+
148+ m_logger->log (" Process took %llu ms" , ILogger::ELL_INFO, time);
149+
150+ // Dump data to JSON
151+ json j;
152+ j[" loaded_files" ] = files;
153+ j[" duration_ms" ] = time;
154+
155+ std::ofstream output (options.outputFile );
156+ if (!output.good ())
157+ {
158+ logFail (" Failed to open %S" , options.outputFile );
159+ return false ;
160+ }
161+
162+ output << j;
163+
164+ return true ;
165+ }
166+
167+ inline bool keepRunning () override
168+ {
169+ return false ;
170+ }
171+
172+ inline void workLoopBody () override
173+ {
174+
175+ }
176+
176177private:
177- struct NBL_APP_OPTIONS
178- {
179- std::string directory;
180- std::string outputFile;
181- } options;
178+ struct NBL_APP_OPTIONS
179+ {
180+ std::string directory;
181+ std::string outputFile;
182+ } options;
182183};
183184
184185NBL_MAIN_FUNC (JpegLoaderApp)
0 commit comments