C++ AMP: Default accelerator in C++ AMP

I have blogged previously about the accelerator and accelerator_view classes in C++ AMP and in this post I want to focus on some specific aspects of its usage.

The notion of default

You can write a lot of useful C++ AMP code without ever needing to learn or use the accelerator and accelerator_view types. That is because when the C++ AMP runtime is initialized (the first time you use some of our types), it picks a default accelerator (i.e. a default target device) where all subsequent operations (such as array allocations and parallel_for_each invocations) take place.

The algorithm for picking a default accelerator should be treated as an implementation detail, but here it is anyway: If you are performing GPU debugging then we pick the accelerator you choose in the project properties, by default the emulator accelerator for debugging (device_path="direct3d/ref" and description=“Software Adapter”); otherwise the environment variable CPPAMP_DEFAULT_ACCELERATOR is examined for a device path. Failing any of those conditions being true, the default is set to a non-emulated device if one exists. If there is more than one, the device with the largest dedicated_memory is chosen. If there is more than one with equal memory, then the one where has_display is false becomes the default one.

It is easy to check what accelerator was picked as the default by simply using the default constructor to initialize an accelerator (which creates the default accelerator)… if you catch my drift.

Setting the default programmatically

You can change the runtime’s default accelerator programmatically only once per process activation, i.e. after you set a default yourself, it cannot be changed again until the process exits (= runtime exits). You can only set a default before you perform any operation that results in the runtime using the default that it picked.

You set the default by calling accelerator::set_default(). Typically you would enumerate all accelerators on the system and then choose the one you want as default, e.g.:

bool pick_accelerator()
{
  std::vector<accelerator> accs = accelerator::get_all();
  accelerator chosen_one;

  auto result = 
    std::find_if(accs.begin(), accs.end(), [] (const accelerator& acc)
    {
      return !acc.is_emulated && 
              acc.supports_double_precision && 
             !acc.has_display;
    });

  if (result != accs.end())
    chosen_one = *(result);

  std::wcout << chosen_one.description << std::endl;

  bool success = accelerator::set_default(chosen_one.device_path);
  return success;
}

accelerator_view

If during the process lifetime you want to change which accelerator you use, or you want different parts of your code to use different accelerators (e.g. to take advantage of multiple accelerators simultaneously), then you need to get an accelerator_view and pass that to the respective API, i.e. array constructor or parallel_for_each dispatch. This is very easy through the default_view property on the accelerator (and now you know how to get one of those), e.g.

accelerator_view av = accelerator(accelerator::direct3d_warp).default_view;

For completeness I should say that you can also call the create_view method on accelerator to get an accelerator_view, as discussed in our blog post on accelerator_view queuing_mode. Since I am truly aiming for completeness, you can also get one of these objects through our DirectX Interop APIs.

 

Your feedback as always is welcome below or in our MSDN forum.

http://blogs.msdn.com/b/nativeconcurrency/archive/2012/02/02/default-accelerator-in-c-amp.aspx

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值