Commit ea4570a3 authored by Peter Steinbach's avatar Peter Steinbach

restructuring cache size calculation

parent bd2c9bc4
......@@ -5,7 +5,7 @@
#include "detail/ct/detect_compiler.hpp"
#include "detail/ct/detect_arch.hpp"
#include "detail/rt/x86_cpuid.hpp"
#include "detail/rt/x86_impl.hpp"
#include "detail/tags.hpp"
#include "detail/bit_view.hpp"
#include "detail/definitions.hpp"
......@@ -22,6 +22,7 @@ namespace compass {
namespace detail {
using bitview = compass::utility::bit_view<std::uint32_t>;
using current_arch_t = ct::arch::type;
namespace size{
......@@ -82,19 +83,13 @@ namespace compass {
class cache
{
std::vector<std::uint32_t> ebx_data_;
std::vector<std::uint32_t> ecx_data_;
cache():
ebx_data_(),
ecx_data_()
{
ebx_data_.reserve(3);
ecx_data_.reserve(3);
std::uint32_t maxlevel = 8;//maximum - 1 that can be mapped to 3 bits in eax[7:5]
std::vector<std::uint32_t> sizes_in_bytes_;
//TODO: refactor this sooner than later
void on_intel() {
std::uint32_t eax = 0;
std::uint32_t maxlevel = 8;//maximum - 1 that can be mapped to 3 bits in eax[7:5]
for(std::uint32_t l = 0;l<maxlevel;++l)
{
......@@ -110,11 +105,43 @@ namespace compass {
if(truelevel != l)//this is the wrong level
continue;
ebx_data_.push_back(regs[ct::ebx]);
ecx_data_.push_back(regs[ct::ecx]);
std::uint32_t ebx = regs[ct::ebx];
const bitview bv_ebx = bitview(ebx);
const std::uint32_t ecx = regs[ct::ecx];
std::uint32_t ways = 1 + bv_ebx.range(22,31);
std::uint32_t partitions = 1 + bv_ebx.range(12,21);
std::uint32_t line_size = 1 + bv_ebx.range(0,11);
std::uint32_t sets = 1 + ecx;
std::uint32_t value = ways*partitions*line_size*sets;
sizes_in_bytes_.push_back(value);
}
}
void on_amd(){
return;
}
cache():
sizes_in_bytes_()
{
sizes_in_bytes_.reserve(8);
auto brand = compass::runtime::detail::vendor( ct::x86_tag() );
if(brand.find("AMD") != std::string::npos){
on_amd():
}
if(brand.find("Intel") != std::string::npos){
on_intel():
}
}
......@@ -126,7 +153,7 @@ namespace compass {
}
static std::uint32_t levels_available(ct::x86_tag){
return cache::get().ebx_data_.size();
return cache::get().sizes_in_bytes_.size();
}
static std::uint32_t level(int _lvl, ct::x86_tag){
......@@ -139,25 +166,15 @@ namespace compass {
std::uint32_t index = _lvl - 1;
if(!(index < cache::get().ebx_data_.size())){
if(!(index < cache::get().sizes_in_bytes_.size())){
std::cerr << "compass::size::cache requested invalid cache level (received: "<<
_lvl << ", found on this host: [1," << cache::get().ebx_data_.size() + 1 << "]\n";
return 0;
}
std::uint32_t ebx = cache::get().ebx_data_[index];
const bitview bv_ebx = bitview(ebx);
const std::uint32_t ecx = cache::get().ecx_data_[index];
std::uint32_t ways = 1 + bv_ebx.range(22,31);
std::uint32_t partitions = 1 + bv_ebx.range(12,21);
std::uint32_t line_size = 1 + bv_ebx.range(0,11);
std::uint32_t sets = 1 + ecx;
std::uint32_t value = ways*partitions*line_size*sets;
return value;
return sizes_in_bytes_[index];
}
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment