Skip to content

Commit

Permalink
feat: Allocate thread resource based on the physical processor
Browse files Browse the repository at this point in the history
The original design has contradiction.
It uses almost all the logical processors for a single PoW,
but allows dcurl to handle 2 PoW at the same time based on the
hyper-threading.

The new function is added in cpu-utils.h to detect the thread number per
physical processor, which also shows whether the hyper-threading is
enabled or not.
Once we know the status of hyper-threading, we can determine the
threadpool size and the thread number for a single PoW.

Close #191.
  • Loading branch information
marktwtn committed Sep 23, 2019
1 parent 3ccfb5a commit cf0db79
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 10 deletions.
5 changes: 5 additions & 0 deletions Doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ INPUT = . \
src
FILE_PATTERNS = dcurl.c \
dcurl.h \
cpu-utils.h \
*.md
USE_MDFILE_AS_MAINPAGE = README.md
#---------------------------------------------------------------------------
Expand All @@ -27,6 +28,10 @@ INLINE_SOURCES = YES
REFERENCED_BY_RELATION = YES
REFERENCES_RELATION = YES
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_STATIC = YES
#---------------------------------------------------------------------------
# Configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = NO
75 changes: 74 additions & 1 deletion src/cpu-utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
#include <sys/sysinfo.h>
#endif

/**
* @file cpu-utils.h
* @brief Utility functions for acquiring CPU information.
*/

/* On Mac OS X, define our own get_nprocs_conf() */
#if defined(__APPLE__) || defined(__FreeBSD__)
#include <sys/sysctl.h>
Expand All @@ -28,7 +33,16 @@ static unsigned int get_nprocs_conf()
}
#endif

static inline int get_avail_nprocs()
/**
* @brief Get the available number of logical processor.
*
* Detect the logical processor number with `get_nproc_conf()`
* or get the number with the environment variable **DCURL_NUM_CPU**.
* @return The available number of logical processor.
* If the environment variable **DCURL_NUM_CPU** is not set, return the
* **maximum logical processor number - 1**.
*/
static inline int get_avail_logic_nprocs()
{
size_t nproc = get_nprocs_conf() - 1;

Expand All @@ -55,3 +69,62 @@ static inline int get_avail_nprocs()
nproc = 1;
return nproc;
}

/**
* @brief Get the thread number per physical processor.
*
* - GNU/Linux: Acquire the thread number by parsing the CPU information.
* - macOS: Acquire the thread number by doing the calculation of
* (logical processor number / physical processor number).
* @return The thread number per physical processor.
* @retval 1 Hyperthreading disabled.
* @retval 2 Hyperthreading enabled.
* @retval -1 Unexpected error.
*/
static inline int get_nthds_per_physic_proc()
{
FILE *fd;
int nthread;
#if defined(__linux__)
char nthd[4];

fd = popen("LC_ALL=C lscpu | grep 'Thread(s) per core' | awk '{printf $4}'",
"r");
if (fd == NULL)
return -1;
if (fgets(nthd, sizeof(nthd), fd) == NULL)
return -1;
nthread = (int) strtol(nthd, NULL, 10);
if (errno == ERANGE || nthread == 0) {
return -1;
}
#elif defined(__APPLE__)
char p_proc[4], l_proc[4];
int physic_proc, logic_proc;

fd = popen("sysctl hw.physicalcpu | awk '{printf $2}'", "r");
if (fd == NULL)
return -1;
if (fgets(p_proc, sizeof(p_proc), fd) == NULL)
return -1;
fd = popen("sysctl hw.logicalcpu | awk '{printf $2}'", "r");
if (fd == NULL)
return -1;
if (fgets(l_proc, sizeof(l_proc), fd) == NULL)
return -1;
physic_proc = (int) strtol(p_proc, NULL, 10);
if (errno == ERANGE || physic_proc == 0) {
return -1;
}
logic_proc = (int) strtol(l_proc, NULL, 10);
if (errno == ERANGE || logic_proc == 0) {
return -1;
}

nthread = logic_proc / physic_proc;
#endif

if (pclose(fd) == -1)
return -1;
return nthread;
}
7 changes: 4 additions & 3 deletions src/pow_avx.c
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,8 @@ static bool PowAVX(void *pow_ctx)

static bool PoWAVX_Context_Initialize(ImplContext *impl_ctx)
{
int nproc = get_avail_nprocs();
impl_ctx->num_max_thread = get_nthds_per_physic_proc();
int nproc = get_avail_logic_nprocs() / impl_ctx->num_max_thread;
if (impl_ctx->num_max_thread <= 0 || nproc <= 0)
return false;

Expand Down Expand Up @@ -609,7 +610,7 @@ static bool PoWAVX_Context_Initialize(ImplContext *impl_ctx)
impl_ctx->bitmap = impl_ctx->bitmap << 1 | 0x1;
uv_loop_init(&ctx[i].loop);
}
uv_set_threadpool_size(nproc);
uv_set_threadpool_size(impl_ctx->num_max_thread * nproc);
impl_ctx->context = ctx;
uv_mutex_init(&impl_ctx->lock);
return true;
Expand Down Expand Up @@ -693,7 +694,7 @@ ImplContext PoWAVX_Context = {
.context = NULL,
.description = "CPU (Intel AVX)",
.bitmap = 0,
.num_max_thread = 2,
.num_max_thread = 0,
.num_working_thread = 0,
.initialize = PoWAVX_Context_Initialize,
.destroy = PoWAVX_Context_Destroy,
Expand Down
7 changes: 4 additions & 3 deletions src/pow_c.c
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,8 @@ bool PowC(void *pow_ctx)

static bool PoWC_Context_Initialize(ImplContext *impl_ctx)
{
int nproc = get_avail_nprocs();
impl_ctx->num_max_thread = get_nthds_per_physic_proc();
int nproc = get_avail_logic_nprocs() / impl_ctx->num_max_thread;
if (impl_ctx->num_max_thread <= 0 || nproc <= 0)
return false;

Expand Down Expand Up @@ -373,7 +374,7 @@ static bool PoWC_Context_Initialize(ImplContext *impl_ctx)
impl_ctx->bitmap = impl_ctx->bitmap << 1 | 0x1;
uv_loop_init(&ctx[i].loop);
}
uv_set_threadpool_size(nproc);
uv_set_threadpool_size(impl_ctx->num_max_thread * nproc);
impl_ctx->context = ctx;
uv_mutex_init(&impl_ctx->lock);
return true;
Expand Down Expand Up @@ -456,7 +457,7 @@ ImplContext PoWC_Context = {
.context = NULL,
.description = "CPU (Pure C)",
.bitmap = 0,
.num_max_thread = 2,
.num_max_thread = 0,
.num_working_thread = 0,
.initialize = PoWC_Context_Initialize,
.destroy = PoWC_Context_Destroy,
Expand Down
7 changes: 4 additions & 3 deletions src/pow_sse.c
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,8 @@ static bool PowSSE(void *pow_ctx)

static bool PoWSSE_Context_Initialize(ImplContext *impl_ctx)
{
int nproc = get_avail_nprocs();
impl_ctx->num_max_thread = get_nthds_per_physic_proc();
int nproc = get_avail_logic_nprocs() / impl_ctx->num_max_thread;
if (impl_ctx->num_max_thread <= 0 || nproc <= 0)
return false;

Expand Down Expand Up @@ -391,7 +392,7 @@ static bool PoWSSE_Context_Initialize(ImplContext *impl_ctx)
impl_ctx->bitmap = impl_ctx->bitmap << 1 | 0x1;
uv_loop_init(&ctx[i].loop);
}
uv_set_threadpool_size(nproc);
uv_set_threadpool_size(impl_ctx->num_max_thread * nproc);
impl_ctx->context = ctx;
uv_mutex_init(&impl_ctx->lock);
return true;
Expand Down Expand Up @@ -475,7 +476,7 @@ ImplContext PoWSSE_Context = {
.context = NULL,
.description = "CPU (Intel SSE)",
.bitmap = 0,
.num_max_thread = 2,
.num_max_thread = 0,
.num_working_thread = 0,
.initialize = PoWSSE_Context_Initialize,
.destroy = PoWSSE_Context_Destroy,
Expand Down

0 comments on commit cf0db79

Please sign in to comment.