Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 18 additions & 8 deletions Code/EntryPoint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <cstdint>
#include <iostream>

#include "GetProcessorInformation.hpp"
#include "GetProcessorCoreInformation.hpp"
#include "OverlappedIOFileRead.hpp"

int main(int argc, const char * argv[]) {
Expand All @@ -14,19 +15,28 @@ int main(int argc, const char * argv[]) {
return -1;
}

auto processor_information = FileReadSpeedTest::GetProcessorInformation();
if (!processor_information.has_value()) {
auto processor_core_information = FileReadSpeedTest::GetProcessorCoreInformation();
if (!processor_core_information.has_value()) {
std::cerr << "Error: Could not find processor information." << std::endl;
return -1;
}

std::cout << "CPU cores: " << processor_information->actual_cores_;
if (processor_information->hyperthreading_cores_ != 0) {
std::cout << " (and " << processor_information->hyperthreading_cores_ << " hyperthreading cores)";
int16_t max_efficiency = -1;
uint16_t max_efficiency_core_count = 0;
for (auto& core_information : *processor_core_information) {
std::cout << "CPU cores: " << core_information.count_ << " @ performance class: " << core_information.efficiency_class_;
if (core_information.has_hyperthreading_ != 0) {
std::cout << " (with hyperthreading)";
}

if (core_information.efficiency_class_ > max_efficiency) {
max_efficiency = core_information.efficiency_class_;
max_efficiency_core_count = core_information.count_;
}
std::cout << std::endl;
}
std::cout << std::endl;

auto overlapped_io_file_read = FileReadSpeedTest::PrepareToReadFile(argv[1], processor_information->actual_cores_);
auto overlapped_io_file_read = FileReadSpeedTest::PrepareToReadFile(argv[1], max_efficiency_core_count);
if (!overlapped_io_file_read.has_value()) {
std::cerr << "Error";
return -1;
Expand Down
68 changes: 68 additions & 0 deletions Code/GetProcessorCoreInformation.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright 2025, The FileReadSpeedTest Contributors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "GetProcessorCoreInformation.hpp"

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <Windows.h>

#include <memory>
#include <utility>

namespace FileReadSpeedTest {

ProcessorCoreInformation::ProcessorCoreInformation(uint16_t efficiency_class, uint16_t count, bool has_hyperthreading) noexcept
: efficiency_class_(std::move(efficiency_class))
, count_(std::move(count))
, has_hyperthreading_(std::move(has_hyperthreading))
{}

std::optional<std::vector<ProcessorCoreInformation>> GetProcessorCoreInformation() noexcept {
DWORD required_buffer_size = 0;
BOOL result = GetLogicalProcessorInformationEx(RelationProcessorCore, nullptr, &required_buffer_size);
if (result == FALSE) {
DWORD error_code = GetLastError();
if (error_code != ERROR_INSUFFICIENT_BUFFER) {
return std::nullopt;
}
}

const size_t element_size = sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX);
// char[] because chars enable aliasing
auto buffer = std::make_unique<char[]>(required_buffer_size);
auto buffer_end = buffer.get() + required_buffer_size;
auto* current_pointer = buffer.get();
auto* processor_information = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)current_pointer;
result = GetLogicalProcessorInformationEx(RelationProcessorCore, processor_information, &required_buffer_size);
if (result == FALSE) {
return std::nullopt;
}

std::vector<ProcessorCoreInformation> core_informations;
for (size_t i = 0; (char*)current_pointer < buffer_end; i++) {
uint32_t efficiency = processor_information->Processor.EfficiencyClass;
bool hyperthreading = processor_information->Processor.Flags == LTP_PC_SMT;

bool match_found = false;
for (auto& core_information : core_informations) {
if (core_information.efficiency_class_ == efficiency &&
core_information.has_hyperthreading_ == hyperthreading) {
match_found = true;
core_information.count_++;
}
}
if (!match_found) {
core_informations.emplace_back(efficiency, 1, hyperthreading);
}

current_pointer += processor_information->Size;
processor_information = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)current_pointer;
}

return core_informations;
}

} // namespace FileReadSpeedTest
28 changes: 28 additions & 0 deletions Code/GetProcessorCoreInformation.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright 2025, The FileReadSpeedTest Contributors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef FILEREADSPEEDTEST_GETPROCESSORCOREINFORMATION_HPP
#define FILEREADSPEEDTEST_GETPROCESSORCOREINFORMATION_HPP

#include <cstdint>
#include <optional>
#include <vector>

namespace FileReadSpeedTest {

struct ProcessorCoreInformation {
public:

explicit ProcessorCoreInformation(uint16_t efficiency_class, uint16_t count, bool has_hyperthreading) noexcept;

uint16_t efficiency_class_;
uint16_t count_;
bool has_hyperthreading_;
};

std::optional<std::vector<ProcessorCoreInformation>> GetProcessorCoreInformation() noexcept;

} // namespace FileReadSpeedTest

#endif // #ifndef FILEREADSPEEDTEST_GETPROCESSORCOREINFORMATION_HPP
98 changes: 0 additions & 98 deletions Code/GetProcessorInformation.cpp

This file was deleted.

22 changes: 0 additions & 22 deletions Code/GetProcessorInformation.hpp

This file was deleted.

4 changes: 2 additions & 2 deletions Projects/VisualStudio/FileReadSpeedTest.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\Code\EntryPoint.cpp" />
<ClCompile Include="..\..\Code\GetProcessorInformation.cpp" />
<ClCompile Include="..\..\Code\GetProcessorCoreInformation.cpp" />
<ClCompile Include="..\..\Code\OSAllocator.cpp" />
<ClCompile Include="..\..\Code\OverlappedIOFileRead.cpp" />
<ClCompile Include="..\..\Code\Win32Types.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\Code\GetProcessorInformation.hpp" />
<ClInclude Include="..\..\Code\GetProcessorCoreInformation.hpp" />
<ClInclude Include="..\..\Code\OSAllocator.hpp" />
<ClInclude Include="..\..\Code\OverlappedIOFileRead.hpp" />
<ClInclude Include="..\..\Code\Win32Types.hpp" />
Expand Down
Loading