c++ - OpenMP 线程与静态变量的关联
问题描述
我有一个 C++ 类 C,其中包含一些代码,包括一个只能读取的静态变量,也许还有一个 constexpr 静态函数。例如:
template<std::size_t T>
class C {
public:
//some functions
void func1();
void func2()
static constexpr std::size_t sfunc1(){ return T; }
private:
std::size_t var1;
std::array<std::size_t,10000> array1;
static int svar1;
}
这个想法是使用openMP 4.5的线程亲和机制来控制执行此类的各种实例的套接字(NUMA架构)(因此也将其放置在靠近套接字的内存位置以避免使用NUMA之间的互连节点)。据我了解,由于此代码包含一个静态变量,因此它在所有类实例之间有效共享,因此在创建线程时,我无法控制放置静态变量的内存位置。这个对吗?但我认为其他非静态变量将位于靠近正在使用的套接字的内存位置?谢谢
解决方案
您必须假设线程堆栈、线程绑定 malloc 和线程本地存储将分配给线程的“本地”内存 - 因此任何自动或新变量都应至少在创建它们的线程上进行优化,尽管我不不知道哪些编译器支持这种分配模型;但正如您所说,静态非常量数据只能存在于一个位置。我猜如果编译器识别 const 段或构造的 const 段,那么在构造之后它们可以按区域复制然后映射到相同的逻辑地址?再次不知道编译器是否会自动执行此操作。
非常量静态会很麻烦。大概这些静态有助于执行某种线程同步。如果它们包含经常读取和很少写入的标志,那么为了获得最佳性能,写入器可能会更好地写入多个注册副本(每个区域一个),并且每个线程使用指向适当区域副本的线程本地指针,超过一半(或 3/4)的读者总是很慢。当然,这不再是简单的原子写入,单个互斥体只会让您回到开始的位置。我怀疑这是你自己的代码领域。
不应该忘记的简单情况:如果对象在线程之间传递,那么线程可能正在访问非本地对象。
推荐阅读
- grails - 将 Groovy 脚本的结果放入 GSP
- javascript - 为什么即使我使用异步和等待,项目的总计数始终为零
- laravel - 当我使用限制或接受 whereIn 时,laravel eger 加载无法正常工作
- javascript - 如何在 CSS/HTML/JS 上创建虚线
- r - 模型未能与 max|grad| 收敛
- android - 如何在 FlatList React Native 中实现复选框
- sql-server - 将日期时间从 12 小时格式转换为 24 小时格式
- javascript - 按字符串数组过滤对象数组
- pyspark - 在满足条件之前返回行值的排序行的火花聚合
- javascript - 在拖动时获取 Div 的新左侧位置百分比