bmx-ng / brl.mod

BlitzMax Runtime Libraries, for BlitzMax NG.
12 stars 11 forks source link

[platform.mod] PhysicalProcessorCount() not working properly on Win32 #302

Closed thareh closed 9 months ago

thareh commented 9 months ago

Good day,

Seems PhysicalProcessorCount() is not working properly on Win32 for me.

SuperStrict

Framework brl.standardio
Import brl.platform

Print "Logal = " + LogicalProcessorCount()
Print "Physical = " + PhysicalProcessorCount()

Gives me:

Logal = 16
Physical = 16

When I have a 16/8 core cpu.

Seems it's not that easy to get the physical core count on windows, I found the following possible solutions:

Windows (x64 and Win32) and C++17

size_t NumberOfPhysicalCores() noexcept {

    DWORD length = 0;
    const BOOL result_first = GetLogicalProcessorInformationEx(RelationProcessorCore, nullptr, &length);
    assert(GetLastError() == ERROR_INSUFFICIENT_BUFFER);

    std::unique_ptr< std::byte[] > buffer(new std::byte[length]);
    const PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX info = 
            reinterpret_cast< PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX >(buffer.get());

    const BOOL result_second = GetLogicalProcessorInformationEx(RelationProcessorCore, info, &length);
    assert(result_second != FALSE);

    size_t nb_physical_cores = 0;
    size_t offset = 0;
    do {
        const PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX current_info =
            reinterpret_cast< PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX >(buffer.get() + offset);
        offset += current_info->Size;
        ++nb_physical_cores;
    } while (offset < length);

    return nb_physical_cores;
}

Boost

#include <iostream>
#include <boost/thread.hpp>

int main()
{
    std::cout << boost::thread::physical_concurrency();
    return 0;
}

Cheers!

thareh commented 9 months ago

The top solution seems to work for me and doesn't require an external library.

#include <brl.mod/blitz.mod/blitz.h>
#include <cassert>
#include <memory>

extern "C" {
    size_t NumberOfPhysicalCores();
}

size_t NumberOfPhysicalCores() noexcept {
    DWORD length = 0;
    const BOOL result_first = GetLogicalProcessorInformationEx(RelationProcessorCore, nullptr, &length);
    assert(GetLastError() == ERROR_INSUFFICIENT_BUFFER);

    std::unique_ptr< std::byte[] > buffer(new std::byte[length]);
    const PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX info = 
            reinterpret_cast< PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX >(buffer.get());

    const BOOL result_second = GetLogicalProcessorInformationEx(RelationProcessorCore, info, &length);
    assert(result_second != FALSE);

    size_t nb_physical_cores = 0;
    size_t offset = 0;
    do {
        const PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX current_info =
            reinterpret_cast< PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX >(buffer.get() + offset);
        offset += current_info->Size;
        ++nb_physical_cores;
    } while (offset < length);

    return nb_physical_cores;
}
Framework BRL.Blitz
Import BRL.StandardIO

Import "Cores.cpp"

Extern
    Function NumberOfPhysicalCores:Size_T()
EndExtern

Print NumberOfPhysicalCores()

I don't know if the solution is good enough or not though.

Cheers.

woollybah commented 9 months ago

The latest update to brl.platform may work for you. Gives me the same answer for my virtual machine :)

thareh commented 9 months ago

It works! Thanks!