【发布时间】:2012-08-12 08:16:33
【问题描述】:
在英特尔 Cilk Plus 扩展中有这个关键字 cilk_for(或实际上是 _Cilk_for)。它类似于 for 的关键字,但更具限制性,并且它的迭代并行运行。我本着 BOOST_FOREACH 的精神写了一个便利宏,它在内部使用了 cilk_for。你能看出以下实现有什么问题吗?
#pragma once
#include <iterator>
#include <boost/preprocessor/cat.hpp>
#include <cilk/cilk.h>
#define cilk_foreach(_decl_var_, _expr_range_) \
CILK_FOREACH_I(_decl_var_, _expr_range_, __COUNTER__)
#define CILK_FOREACH_I(_decl_var_, _expr_range_, _id_) \
CILK_FOREACH_II(_decl_var_, \
_expr_range_, \
BOOST_PP_CAT(_range_3s236dw221GyVcf46_, _id_), \
BOOST_PP_CAT(_end_5Y60u42bIp7DZd88f2c_, _id_), \
BOOST_PP_CAT(_itr_6V970q8n4Etv0i8bf50_, _id_), \
BOOST_PP_CAT(_continue_4rtWH641r5cXqU_, _id_))
#define CILK_FOREACH_II(_decl_var_, _expr_range_, _range_, _end_, _itr_, _cont_) \
auto&& _range_ = _expr_range_; \
auto _end_ = std::end(_range_); \
\
cilk_for (auto _itr_ = std::begin(_range_); _itr_ != _end_; ++_itr_) \
if (auto _cont_ = true) \
for (_decl_var_ = *_itr_; _cont_; _cont_ = false)
你会这样使用它:
std::vector<int> values (10);
cilk_foreach (auto& value , values)
{
value += 123;
}
编辑
template <typename T>
struct Wrap
{
T& data;
explicit Wrap(T&& data)
: data (data)
{}
operator bool() const
{
return true;
}
};
template <typename T>
Wrap<T> wrap(T&& data)
{
return Wrap<T>(std::forward<T>(data));
}
#define cilk_foreach(_decl_var_, _expr_range_) \
CILK_FOREACH_I(_decl_var_, _expr_range_, __COUNTER__)
#define CILK_FOREACH_I(_decl_var_, _expr_range_, _id_) \
\
CILK_FOREACH_II(_decl_var_, \
_expr_range_, \
BOOST_PP_CAT(_range_3s236dw221GyVcf46_, _id_), \
BOOST_PP_CAT(_itr_6V970q8n4Etv0i8bf50_, _id_), \
BOOST_PP_CAT(_continue_4rtWH641r5cXqU_, _id_))
#define CILK_FOREACH_II(_decl_var_, _expr_range_, _range_, _itr_, _cont_) \
\
if (auto _range_ = wrap(_expr_range_)) \
cilk_for (auto _itr_ = std::begin(_range_.data); \
_itr_ != std::end (_range_.data); \
++_itr_) \
if (auto _cont_ = true) \
for (_decl_var_ = *_itr_; _cont_; _cont_ = false)
【问题讨论】:
-
是的,它似乎确实有效,因为我测试的很少。我只是对为什么 BOOST_FOREACH 实现如此复杂感到困惑,如果像上面这样的简单实现也可以工作的话。显然 cilk_for 的所有限制仍然适用,例如范围需要随机访问。
-
很好,但是这比 std::for_each 有什么好处?
-
@dans3itz:我的 cilk_foreach 宏(通过 cilk_for)的好处是可以尽可能多地并行运行它的迭代。
-
嗯,有道理。为此,我正在查看 TBB 的 parallel_for;但我缺乏比较的经验。欣赏解释。
标签: c++ c++11 macros foreach cilk-plus