|
Packit |
345191 |
/*
|
|
Packit |
345191 |
* Copyright (C) 2017 - 2019 Intel Corporation.
|
|
Packit |
345191 |
* All rights reserved.
|
|
Packit |
345191 |
*
|
|
Packit |
345191 |
* Redistribution and use in source and binary forms, with or without
|
|
Packit |
345191 |
* modification, are permitted provided that the following conditions are met:
|
|
Packit |
345191 |
* 1. Redistributions of source code must retain the above copyright notice(s),
|
|
Packit |
345191 |
* this list of conditions and the following disclaimer.
|
|
Packit |
345191 |
* 2. Redistributions in binary form must reproduce the above copyright notice(s),
|
|
Packit |
345191 |
* this list of conditions and the following disclaimer in the documentation
|
|
Packit |
345191 |
* and/or other materials provided with the distribution.
|
|
Packit |
345191 |
*
|
|
Packit |
345191 |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY EXPRESS
|
|
Packit |
345191 |
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
Packit |
345191 |
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
|
Packit |
345191 |
* EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
Packit |
345191 |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
Packit |
345191 |
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
Packit |
345191 |
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
Packit |
345191 |
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
|
Packit |
345191 |
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
Packit |
345191 |
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
Packit |
345191 |
*/
|
|
Packit |
345191 |
|
|
Packit |
345191 |
#include <stdio.h>
|
|
Packit |
345191 |
#include <numa.h>
|
|
Packit |
345191 |
#include <hbwmalloc.h>
|
|
Packit |
345191 |
#include <memkind.h>
|
|
Packit |
345191 |
#include <vector>
|
|
Packit |
345191 |
#include <memory>
|
|
Packit |
345191 |
#include <gtest/gtest.h>
|
|
Packit |
345191 |
#include "allocator_perf_tool/Allocation_info.hpp"
|
|
Packit |
345191 |
#include "allocator_perf_tool/GTestAdapter.hpp"
|
|
Packit |
345191 |
|
|
Packit |
345191 |
typedef std::unique_ptr<void, void(*)(void *)> hbw_mem_ptr;
|
|
Packit |
345191 |
|
|
Packit |
345191 |
|
|
Packit |
345191 |
class HBWPreferredLocalityTest: public ::testing::Test
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
private:
|
|
Packit |
345191 |
int find_closest_node(int node, const std::vector<int> &nodes)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
int min_distance = 0;
|
|
Packit |
345191 |
int closest_node = -1;
|
|
Packit |
345191 |
for (int i = 0; i < nodes.size(); i++) {
|
|
Packit |
345191 |
int distance = numa_distance(node, nodes[i]);
|
|
Packit |
345191 |
if (distance && (distance < min_distance || min_distance == 0)) {
|
|
Packit |
345191 |
min_distance = distance;
|
|
Packit |
345191 |
closest_node = nodes[i];
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
return closest_node;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
bool pin_to_cpu(int cpu_id)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
cpu_set_t cpu_set;
|
|
Packit |
345191 |
CPU_ZERO(&cpu_set);
|
|
Packit |
345191 |
CPU_SET(cpu_id, &cpu_set);
|
|
Packit |
345191 |
return sched_setaffinity(0, sizeof(cpu_set_t), &cpu_set) != -1;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
void check_ptr_numa(void *ptr, int expected_numa_id, int cpu_id, size_t size)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
memset(ptr, 1, size);
|
|
Packit |
345191 |
|
|
Packit |
345191 |
int numa_id = get_numa_node_id(ptr);
|
|
Packit |
345191 |
EXPECT_EQ(numa_id, expected_numa_id);
|
|
Packit |
345191 |
|
|
Packit |
345191 |
char property_name[50];
|
|
Packit |
345191 |
snprintf(property_name, 50, "actual_numa_for_cpu_%d_expected_numa_%d", cpu_id,
|
|
Packit |
345191 |
expected_numa_id);
|
|
Packit |
345191 |
GTestAdapter::RecordProperty(property_name, numa_id);
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
public:
|
|
Packit |
345191 |
void pin_memory_in_requesting_mem_thread(size_t size,
|
|
Packit |
345191 |
const std::vector<int> &cpu_ids,
|
|
Packit |
345191 |
const std::vector<int> &mcdram_nodes)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
#ifdef _OPENMP
|
|
Packit |
345191 |
int threads_num = cpu_ids.size();
|
|
Packit |
345191 |
int ret = hbw_set_policy(HBW_POLICY_PREFERRED);
|
|
Packit |
345191 |
ASSERT_EQ(ret, 0);
|
|
Packit |
345191 |
|
|
Packit |
345191 |
#pragma omp parallel for num_threads(threads_num)
|
|
Packit |
345191 |
for (int i = 0; i < threads_num; i++) {
|
|
Packit |
345191 |
if (!pin_to_cpu(cpu_ids[i])) {
|
|
Packit |
345191 |
ADD_FAILURE();
|
|
Packit |
345191 |
continue;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
void *internal_ptr = hbw_malloc(size);
|
|
Packit |
345191 |
if (!internal_ptr) {
|
|
Packit |
345191 |
ADD_FAILURE();
|
|
Packit |
345191 |
continue;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
hbw_mem_ptr ptr(internal_ptr, hbw_free);
|
|
Packit |
345191 |
int expected_numa_id = find_closest_node(numa_node_of_cpu(cpu_ids[i]),
|
|
Packit |
345191 |
mcdram_nodes);
|
|
Packit |
345191 |
check_ptr_numa(ptr.get(), expected_numa_id, cpu_ids[i], size);
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
#else
|
|
Packit |
345191 |
std::cout << "[ SKIPPED ] Feature OPENMP not supported" << std::endl;
|
|
Packit |
345191 |
#endif
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
void pin_memory_in_other_thread_than_requesting_mem(size_t size,
|
|
Packit |
345191 |
const std::vector<int> &cpu_ids,
|
|
Packit |
345191 |
const std::vector<int> &mcdram_nodes)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
#ifdef _OPENMP
|
|
Packit |
345191 |
int threads_num = cpu_ids.size();
|
|
Packit |
345191 |
int ret = hbw_set_policy(HBW_POLICY_PREFERRED);
|
|
Packit |
345191 |
ASSERT_EQ(ret, 0);
|
|
Packit |
345191 |
|
|
Packit |
345191 |
int main_thread_cpu_id = 0;
|
|
Packit |
345191 |
int expected_numa_id = find_closest_node(main_thread_cpu_id, mcdram_nodes);
|
|
Packit |
345191 |
ASSERT_TRUE(pin_to_cpu(main_thread_cpu_id));
|
|
Packit |
345191 |
|
|
Packit |
345191 |
std::vector<hbw_mem_ptr> ptrs;
|
|
Packit |
345191 |
for (int i = 0; i < threads_num; i++) {
|
|
Packit |
345191 |
void *internal_ptr = hbw_malloc(size);
|
|
Packit |
345191 |
ASSERT_TRUE(internal_ptr);
|
|
Packit |
345191 |
ptrs.emplace_back(internal_ptr, hbw_free);
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
#pragma omp parallel for num_threads(threads_num)
|
|
Packit |
345191 |
for (int i = 0; i < threads_num; i++) {
|
|
Packit |
345191 |
if (!pin_to_cpu(cpu_ids[i])) {
|
|
Packit |
345191 |
ADD_FAILURE();
|
|
Packit |
345191 |
continue;
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
check_ptr_numa(ptrs[i].get(), expected_numa_id, cpu_ids[i], size);
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
#else
|
|
Packit |
345191 |
std::cout << "[ SKIPPED ] Feature OPENMP not supported" << std::endl;
|
|
Packit |
345191 |
#endif
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
};
|
|
Packit |
345191 |
|
|
Packit |
345191 |
TEST_F(HBWPreferredLocalityTest,
|
|
Packit |
345191 |
test_TC_MEMKIND_KNL_SNC4_pin_memory_in_requesting_mem_thread_4_threads_100_bytes)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
pin_memory_in_requesting_mem_thread(100u, std::vector<int> {0, 18, 36, 54},
|
|
Packit |
345191 |
std::vector<int> {4, 5, 6, 7});
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|
|
Packit |
345191 |
TEST_F(HBWPreferredLocalityTest,
|
|
Packit |
345191 |
test_TC_MEMKIND_KNL_SNC4_pin_memory_in_other_thread_than_requesting_mem_4_threads_100_bytes)
|
|
Packit |
345191 |
{
|
|
Packit |
345191 |
pin_memory_in_other_thread_than_requesting_mem(100u, std::vector<int> {0, 18, 36, 54},
|
|
Packit |
345191 |
std::vector<int> {4, 5, 6, 7});
|
|
Packit |
345191 |
}
|
|
Packit |
345191 |
|