thread::hardware_concurrency() 作为模板参数
Posted
技术标签:
【中文标题】thread::hardware_concurrency() 作为模板参数【英文标题】:thread::hardware_concurrency() as template parameter 【发布时间】:2017-07-20 10:46:15 【问题描述】:我有一个模板类,它带有一个 unsigned int 参数来表示线程数。我想用它来为线程创建一个静态数组。
我既不能使用std::thread::hardware_concurrency()
作为默认值,
template <typename T, size_t num_threads = std::thread::hardware_concurrency()>
class Some_class
T values[num_threads];
...
也不把它作为参数给我的班级。
template <typename T, size_t num_threads>
class Some_class
T values[num_threads];
...
Some_class<int,std::thread::hardware_concurrency()> instance;
问题是std::thread::hardware_concurrency()
s的返回值不是const。
编译器说:
error: call to non-constexpr function ‘static unsigned int std::thread::hardware_concurrency()’
note: in template argument for type ‘long unsigned int’
还有其他静态方法可以获取模板的可用线程数吗?
【问题讨论】:
您只能在 C++ 模板中使用 常量表达式。不幸的是,std::thread::hardware_concurrency()
不是一个常量表达式,它只能在运行时计算
您使用的是哪个操作系统,哪个编译器?
【参考方案1】:
还有其他静态方法可以获取模板的可用线程数吗?
答案是NO,因为std::thread::hardware_concurrency() 不是constexpr 函数(并发线程的数量可能会因程序运行所在的系统而异,所以它绝对合乎逻辑,对吗?),但num_threads
必须使用编译时常量进行初始化。
您可能会处理一些变通方法,例如使用 std::vector
而不是数组:
template <typename T>
class SomeClass
public:
SomeClass()
: values(std::thread::hardware_concurrency())
private:
std::vector<T> values;
;
【讨论】:
无关位。在查看标准时,我发现std::hardware_concurrency
不是 constexpr
而 std::hardware_constructive_interference_size
是 constexpr
很奇怪。
@WhiZTiM 这实际上是非常合理的。 ..interferanace_size
1) 必须是编译时用于控制内存布局的主要用途,例如与alignas
。 2) 实际上可以在编译时可靠地确定 - 另请参阅open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0154r0.html【参考方案2】:
没有获取系统上逻辑 CPU 数量的静态方法。这个数字可以很容易地在编译和执行之间改变,例如如果二进制文件在不同的系统上执行。
您可以从构建系统中获取编译代码的系统逻辑 CPU 的数量,例如使用 CMake's ProcessorCount 并将其放入定义中。
【讨论】:
听起来不错!我如何在我的程序中使用这个数字作为你已经说过的定义? 我只是设法得到它。我在link 的示例中设置了线程数,并添加了:set ( CMAKE_CXX_FLAGS -DTHREADS=$N)
现在我可以在我的模板中使用它。非常感谢
很高兴你能成功。只是一点提示:你可以使用add_definitions(-DTHREADS=$N)
,它比使用CMAKE_CXX_FLAGS
更优雅,尤其是如果它们是之前设置的。以上是关于thread::hardware_concurrency() 作为模板参数的主要内容,如果未能解决你的问题,请参考以下文章