diff --git a/CMakeLists.txt b/CMakeLists.txt
index 48946c7ed..8291f6067 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -33,9 +33,6 @@ set(HEADERS
     src/core/config/ConfigTransform.h
     src/core/config/usage.h
     src/core/Controller.h
-    src/core/WorkerJob.h
-    src/interfaces/IThread.h
-    src/interfaces/IWorker.h
     src/Mem.h
     src/net/interfaces/IJobResultListener.h
     src/net/JobResult.h
@@ -47,9 +44,7 @@ set(HEADERS
     src/version.h
     src/workers/CpuThreadLegacy.h
     src/workers/Hashrate.h
-    src/workers/MultiWorker.h
     src/workers/ThreadHandle.h
-    src/workers/Worker.h
     src/workers/Workers.h
    )
 
@@ -97,9 +92,7 @@ set(SOURCES
     src/Summary.cpp
     src/workers/CpuThreadLegacy.cpp
     src/workers/Hashrate.cpp
-    src/workers/MultiWorker.cpp
     src/workers/ThreadHandle.cpp
-    src/workers/Worker.cpp
     src/workers/Workers.cpp
     src/xmrig.cpp
    )
diff --git a/src/api/v1/ApiRouter.cpp b/src/api/v1/ApiRouter.cpp
index 18d97fdab..5ed94c4b6 100644
--- a/src/api/v1/ApiRouter.cpp
+++ b/src/api/v1/ApiRouter.cpp
@@ -29,11 +29,11 @@
 
 #include "api/interfaces/IApiRequest.h"
 #include "api/v1/ApiRouter.h"
+#include "backend/common/interfaces/IThread.h"
 #include "backend/cpu/Cpu.h"
 #include "base/kernel/Base.h"
 #include "base/kernel/Platform.h"
 #include "core/config/Config.h"
-#include "interfaces/IThread.h"
 #include "rapidjson/document.h"
 #include "version.h"
 #include "workers/Hashrate.h"
diff --git a/src/backend/backend.cmake b/src/backend/backend.cmake
index 750cc9cbd..c37cf262a 100644
--- a/src/backend/backend.cmake
+++ b/src/backend/backend.cmake
@@ -1,12 +1,13 @@
 include (src/backend/cpu/cpu.cmake)
+include (src/backend/common/common.cmake)
 
 
 set(HEADERS_BACKEND
-    "${HEADERS_CPU}"
-    src/backend/Threads.h
+    "${HEADERS_BACKEND_COMMON}"
+    "${HEADERS_BACKEND_CPU}"
    )
 
 set(SOURCES_BACKEND
-    "${SOURCES_CPU}"
-    src/backend/Threads.cpp
+    "${SOURCES_BACKEND_COMMON}"
+    "${SOURCES_BACKEND_CPU}"
    )
diff --git a/src/backend/Threads.cpp b/src/backend/common/Threads.cpp
similarity index 99%
rename from src/backend/Threads.cpp
rename to src/backend/common/Threads.cpp
index 11e1ec153..4cb9d4c66 100644
--- a/src/backend/Threads.cpp
+++ b/src/backend/common/Threads.cpp
@@ -23,8 +23,8 @@
  */
 
 
+#include "backend/common/Threads.h"
 #include "backend/cpu/CpuThread.h"
-#include "backend/Threads.h"
 #include "rapidjson/document.h"
 
 
diff --git a/src/backend/Threads.h b/src/backend/common/Threads.h
similarity index 100%
rename from src/backend/Threads.h
rename to src/backend/common/Threads.h
diff --git a/src/workers/Worker.cpp b/src/backend/common/Worker.cpp
similarity index 98%
rename from src/workers/Worker.cpp
rename to src/backend/common/Worker.cpp
index d85858af0..f0457bbb1 100644
--- a/src/workers/Worker.cpp
+++ b/src/backend/common/Worker.cpp
@@ -26,11 +26,11 @@
 #include <chrono>
 
 
+#include "backend/common/Worker.h"
 #include "backend/cpu/Cpu.h"
 #include "base/kernel/Platform.h"
 #include "workers/CpuThreadLegacy.h"
 #include "workers/ThreadHandle.h"
-#include "workers/Worker.h"
 
 
 Worker::Worker(ThreadHandle *handle) :
diff --git a/src/workers/Worker.h b/src/backend/common/Worker.h
similarity index 97%
rename from src/workers/Worker.h
rename to src/backend/common/Worker.h
index 997771b01..3e1d202fd 100644
--- a/src/workers/Worker.h
+++ b/src/backend/common/Worker.h
@@ -31,7 +31,7 @@
 #include <stdint.h>
 
 
-#include "interfaces/IWorker.h"
+#include "backend/common/interfaces/IWorker.h"
 #include "Mem.h"
 
 
diff --git a/src/core/WorkerJob.h b/src/backend/common/WorkerJob.h
similarity index 100%
rename from src/core/WorkerJob.h
rename to src/backend/common/WorkerJob.h
diff --git a/src/backend/common/common.cmake b/src/backend/common/common.cmake
new file mode 100644
index 000000000..e7caa593c
--- /dev/null
+++ b/src/backend/common/common.cmake
@@ -0,0 +1,12 @@
+set(HEADERS_BACKEND_COMMON
+    src/backend/common/interfaces/IThread.h
+    src/backend/common/interfaces/IWorker.h
+    src/backend/common/Threads.h
+    src/backend/common/Worker.h
+    src/backend/common/WorkerJob.h
+   )
+
+set(SOURCES_BACKEND_COMMON
+    src/backend/common/Threads.cpp
+    src/backend/common/Worker.cpp
+   )
diff --git a/src/interfaces/IThread.h b/src/backend/common/interfaces/IThread.h
similarity index 100%
rename from src/interfaces/IThread.h
rename to src/backend/common/interfaces/IThread.h
diff --git a/src/interfaces/IWorker.h b/src/backend/common/interfaces/IWorker.h
similarity index 100%
rename from src/interfaces/IWorker.h
rename to src/backend/common/interfaces/IWorker.h
diff --git a/src/backend/cpu/CpuConfig.h b/src/backend/cpu/CpuConfig.h
index 66da3a5ff..88222ab11 100644
--- a/src/backend/cpu/CpuConfig.h
+++ b/src/backend/cpu/CpuConfig.h
@@ -26,8 +26,8 @@
 #define XMRIG_CPUCONFIG_H
 
 
+#include "backend/common/Threads.h"
 #include "backend/cpu/CpuThread.h"
-#include "backend/Threads.h"
 #include "crypto/common/Assembly.h"
 
 
diff --git a/src/workers/MultiWorker.cpp b/src/backend/cpu/CpuWorker.cpp
similarity index 90%
rename from src/workers/MultiWorker.cpp
rename to src/backend/cpu/CpuWorker.cpp
index 1f06455a0..fc98048db 100644
--- a/src/workers/MultiWorker.cpp
+++ b/src/backend/cpu/CpuWorker.cpp
@@ -27,13 +27,13 @@
 #include <thread>
 
 
+#include "backend/cpu/CpuWorker.h"
 #include "crypto/cn/CryptoNight_test.h"
 #include "crypto/common/Nonce.h"
 #include "crypto/rx/Rx.h"
 #include "crypto/rx/RxVm.h"
 #include "net/JobResults.h"
 #include "workers/CpuThreadLegacy.h"
-#include "workers/MultiWorker.h"
 #include "workers/Workers.h"
 
 
@@ -45,7 +45,7 @@ static constexpr uint32_t kReserveCount = 4096;
 
 
 template<size_t N>
-xmrig::MultiWorker<N>::MultiWorker(ThreadHandle *handle)
+xmrig::CpuWorker<N>::CpuWorker(ThreadHandle *handle)
     : Worker(handle)
 {
     if (m_thread->algorithm().family() != Algorithm::RANDOM_X) {
@@ -55,7 +55,7 @@ xmrig::MultiWorker<N>::MultiWorker(ThreadHandle *handle)
 
 
 template<size_t N>
-xmrig::MultiWorker<N>::~MultiWorker()
+xmrig::CpuWorker<N>::~CpuWorker()
 {
     Mem::release(m_ctx, N, m_memory);
 
@@ -67,7 +67,7 @@ xmrig::MultiWorker<N>::~MultiWorker()
 
 #ifdef XMRIG_ALGO_RANDOMX
 template<size_t N>
-void xmrig::MultiWorker<N>::allocateRandomX_VM()
+void xmrig::CpuWorker<N>::allocateRandomX_VM()
 {
     if (!m_vm) {
         RxDataset *dataset = Rx::dataset(m_job.currentJob().seedHash(), m_job.currentJob().algorithm());
@@ -78,7 +78,7 @@ void xmrig::MultiWorker<N>::allocateRandomX_VM()
 
 
 template<size_t N>
-bool xmrig::MultiWorker<N>::selfTest()
+bool xmrig::CpuWorker<N>::selfTest()
 {
     if (m_thread->algorithm().family() == Algorithm::CN) {
         const bool rc = verify(Algorithm::CN_0,      test_output_v0)   &&
@@ -137,7 +137,7 @@ bool xmrig::MultiWorker<N>::selfTest()
 
 
 template<size_t N>
-void xmrig::MultiWorker<N>::start()
+void xmrig::CpuWorker<N>::start()
 {
     while (Nonce::sequence() > 0) {
         if (Workers::isPaused()) {
@@ -189,7 +189,7 @@ void xmrig::MultiWorker<N>::start()
 
 
 template<size_t N>
-bool xmrig::MultiWorker<N>::verify(const Algorithm &algorithm, const uint8_t *referenceValue)
+bool xmrig::CpuWorker<N>::verify(const Algorithm &algorithm, const uint8_t *referenceValue)
 {
     cn_hash_fun func = m_thread->fn(algorithm);
     if (!func) {
@@ -202,7 +202,7 @@ bool xmrig::MultiWorker<N>::verify(const Algorithm &algorithm, const uint8_t *re
 
 
 template<size_t N>
-bool xmrig::MultiWorker<N>::verify2(const Algorithm &algorithm, const uint8_t *referenceValue)
+bool xmrig::CpuWorker<N>::verify2(const Algorithm &algorithm, const uint8_t *referenceValue)
 {
     cn_hash_fun func = m_thread->fn(algorithm);
     if (!func) {
@@ -231,7 +231,7 @@ bool xmrig::MultiWorker<N>::verify2(const Algorithm &algorithm, const uint8_t *r
 namespace xmrig {
 
 template<>
-bool MultiWorker<1>::verify2(const Algorithm &algorithm, const uint8_t *referenceValue)
+bool CpuWorker<1>::verify2(const Algorithm &algorithm, const uint8_t *referenceValue)
 {
     cn_hash_fun func = m_thread->fn(algorithm);
     if (!func) {
@@ -253,7 +253,7 @@ bool MultiWorker<1>::verify2(const Algorithm &algorithm, const uint8_t *referenc
 
 
 template<size_t N>
-void xmrig::MultiWorker<N>::consumeJob()
+void xmrig::CpuWorker<N>::consumeJob()
 {
     m_job.add(Workers::job(), Nonce::sequence(), kReserveCount);
 }
@@ -261,11 +261,11 @@ void xmrig::MultiWorker<N>::consumeJob()
 
 namespace xmrig {
 
-template class MultiWorker<1>;
-template class MultiWorker<2>;
-template class MultiWorker<3>;
-template class MultiWorker<4>;
-template class MultiWorker<5>;
+template class CpuWorker<1>;
+template class CpuWorker<2>;
+template class CpuWorker<3>;
+template class CpuWorker<4>;
+template class CpuWorker<5>;
 
 } // namespace xmrig
 
diff --git a/src/workers/MultiWorker.h b/src/backend/cpu/CpuWorker.h
similarity index 78%
rename from src/workers/MultiWorker.h
rename to src/backend/cpu/CpuWorker.h
index 2bcb2333e..7e878b54d 100644
--- a/src/workers/MultiWorker.h
+++ b/src/backend/cpu/CpuWorker.h
@@ -23,15 +23,15 @@
  *   along with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef XMRIG_MULTIWORKER_H
-#define XMRIG_MULTIWORKER_H
+#ifndef XMRIG_CPUWORKER_H
+#define XMRIG_CPUWORKER_H
 
 
+#include "backend/common/WorkerJob.h"
 #include "base/net/stratum/Job.h"
-#include "core/WorkerJob.h"
 #include "Mem.h"
 #include "net/JobResult.h"
-#include "workers/Worker.h"
+#include "backend/common/Worker.h"
 
 
 namespace xmrig {
@@ -41,11 +41,11 @@ class RxVm;
 
 
 template<size_t N>
-class MultiWorker : public Worker
+class CpuWorker : public Worker
 {
 public:
-    MultiWorker(ThreadHandle *handle);
-    ~MultiWorker();
+    CpuWorker(ThreadHandle *handle);
+    ~CpuWorker() override;
 
 protected:
     bool selfTest() override;
@@ -71,7 +71,18 @@ private:
 };
 
 
+template<>
+bool CpuWorker<1>::verify2(const Algorithm &algorithm, const uint8_t *referenceValue);
+
+
+extern template class CpuWorker<1>;
+extern template class CpuWorker<2>;
+extern template class CpuWorker<3>;
+extern template class CpuWorker<4>;
+extern template class CpuWorker<5>;
+
+
 } // namespace xmrig
 
 
-#endif /* XMRIG_MULTIWORKER_H */
+#endif /* XMRIG_CPUWORKER_H */
diff --git a/src/backend/cpu/cpu.cmake b/src/backend/cpu/cpu.cmake
index df9b7cea6..3e15a9fd6 100644
--- a/src/backend/cpu/cpu.cmake
+++ b/src/backend/cpu/cpu.cmake
@@ -1,14 +1,16 @@
-set(HEADERS_CPU
-	src/backend/cpu/Cpu.h
-	src/backend/cpu/CpuConfig.h
+set(HEADERS_BACKEND_CPU
+    src/backend/cpu/Cpu.h
+    src/backend/cpu/CpuConfig.h
     src/backend/cpu/CpuThread.h
-	src/backend/cpu/interfaces/ICpuInfo.h
+    src/backend/cpu/CpuWorker.h
+    src/backend/cpu/interfaces/ICpuInfo.h
    )
 
-set(SOURCES_CPU
+set(SOURCES_BACKEND_CPU
     src/backend/cpu/Cpu.cpp
     src/backend/cpu/CpuConfig.cpp
     src/backend/cpu/CpuThread.cpp
+    src/backend/cpu/CpuWorker.cpp
    )
 
 
diff --git a/src/workers/CpuThreadLegacy.h b/src/workers/CpuThreadLegacy.h
index 4553295c7..b803a8c43 100644
--- a/src/workers/CpuThreadLegacy.h
+++ b/src/workers/CpuThreadLegacy.h
@@ -26,8 +26,8 @@
 #define XMRIG_CPUTHREADLEGACY_H
 
 
+#include "backend/common/interfaces/IThread.h"
 #include "crypto/cn/CnHash.h"
-#include "interfaces/IThread.h"
 
 
 struct cryptonight_ctx;
diff --git a/src/workers/ThreadHandle.h b/src/workers/ThreadHandle.h
index c32aabf04..aedb49073 100644
--- a/src/workers/ThreadHandle.h
+++ b/src/workers/ThreadHandle.h
@@ -31,7 +31,7 @@
 #include <uv.h>
 
 
-#include "interfaces/IThread.h"
+#include "backend/common/interfaces/IThread.h"
 
 
 class IWorker;
diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp
index 53a8b7124..b43546cd3 100644
--- a/src/workers/Workers.cpp
+++ b/src/workers/Workers.cpp
@@ -28,6 +28,7 @@
 
 
 #include "api/Api.h"
+#include "backend/cpu/CpuWorker.h"
 #include "base/io/log/Log.h"
 #include "base/tools/Chrono.h"
 #include "base/tools/Handle.h"
@@ -37,11 +38,9 @@
 #include "crypto/rx/RxAlgo.h"
 #include "crypto/rx/RxCache.h"
 #include "crypto/rx/RxDataset.h"
-#include "interfaces/IThread.h"
 #include "Mem.h"
 #include "rapidjson/document.h"
 #include "workers/Hashrate.h"
-#include "workers/MultiWorker.h"
 #include "workers/ThreadHandle.h"
 #include "workers/Workers.h"
 
@@ -250,26 +249,23 @@ void Workers::onReady(void *arg)
 
     switch (handle->config()->multiway()) {
     case 1:
-        worker = new xmrig::MultiWorker<1>(handle);
+        worker = new xmrig::CpuWorker<1>(handle);
         break;
 
     case 2:
-        worker = new xmrig::MultiWorker<2>(handle);
+        worker = new xmrig::CpuWorker<2>(handle);
         break;
 
     case 3:
-        worker = new xmrig::MultiWorker<3>(handle);
+        worker = new xmrig::CpuWorker<3>(handle);
         break;
 
     case 4:
-        worker = new xmrig::MultiWorker<4>(handle);
+        worker = new xmrig::CpuWorker<4>(handle);
         break;
 
     case 5:
-        worker = new xmrig::MultiWorker<5>(handle);
-        break;
-
-    default:
+        worker = new xmrig::CpuWorker<5>(handle);
         break;
     }