Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
In Visual Studio 2012, C++ AMP introduced concurrency::array_view as a primary interface to read and write multi-dimensional data across the CPU and GPU accelerators.
The construction of array_view always required a data source like std::vector, concurrency::array etc. It could be either a CPU pointer or any data container that supports .data() and .size() methods . Even in the scenarios, where a temporary container is required purely as an output buffer and its initial content and backing memory allocation is irrelevant, it is mandated to provide a data source.
Look the below code snippets which illustrate the above point.
Example 1:
1: array_view<const int, 1> arrViewA(M, vecA); // vecA is a const data source of type 'std::vector'
2: array_view<const int, 1> arrViewB(M, vecB); // vecB is a const data source of type 'std::vector
3:
4: std::vector<int> sumResult(arrViewA.extent.size());
5: array_view<int, 1> arrViewSum(M,sumResult); // Creation of array_view with resource
6: arrViewSum.discard_data();
7:
8: parallel_for_each(arrViewSum.extent, [=](const index<1> &idx) restrict(amp) {
9: arrViewSum[idx] = arrViewA[idx] + arrViewB[idx];
10: });
11: arrViewSum.synchronize();
12:
13: for (size_t i = 0; i < sumResult.size(); ++i) {
14: sumResult[i]; // Accessing the result of computation
15: }
Example 2:
1: array_view<const int, 1> arrViewA(M, vecA); // vecA is a const data source of type 'std::vector'
2: array_view<const int, 1> arrViewB(M, vecB); // vecB is a const data source of type 'std::vector'
3:
4: array<int, 1> arrSumResult(arrViewA.extent); // Creating Array object as output buffer
5: array_view<int, 1> arrViewSum(arrSumResult); // Creation of array_view over array
6: arrViewSum.discard_data();
7:
8: parallel_for_each(arrViewSum.extent, [=](const index<1> &idx) restrict(amp) {
9: arrViewSum[idx] = arrViewA[idx] + arrViewB[idx];
10: });
11:
12: for (size_t i = 0; i < sumResult.size(); ++i) {
13: arrViewSum.data[i]; // Accessing the result of computation
14: }
From the above code snippets, we will observe the following shortcomings:
a) Always a data source is required during to array_view construction
b) Requires the developers to learn about concurrency::array, array_view::discard_data.
c) Requires allocating the array on the right accelerator_view where, the array_view will be subsequently accessed. It also requires the users to specify the right accelerator_view to p_f_e, for using the array_view. Failure to specify the right accelerator_view may result in redundant data transfers to the targeted accelerator_view.
In Visual Studio 2013, these shortcomings have been addressed with the provision of “array_view construction without specifying a data source”. In short, this can be considered as creating an array_view, without any data source association and let the runtime allocate the underlying storage lazily as and when the array_view is accessed on accelerator_view or on the CPU.
- array_view without data source can be used only for read-write access. It cannot be constructed for read only purpose i.e., array_view<const T>.
- array_view without data source is just like any other ‘array_view’ object with no data association.
- array_view is initially uninitialized and behaves as if its contents have been “discard” immediately after construction.
- The “synchronize” API (the overload without any accelerator_view explicitly specified) will be a no-op for such an array_view.
Now, let’s rewrite the code snippets given in ‘Example 1’ and ‘Example 2’ using ‘array_view without data source’.
1: array_view<const int, 1> arrViewA(M, vecA); // vecA is a const data source of type 'std::vector'
2: array_view<const int, 1> arrViewB(M, vecB); // vecB is a const data source of type 'std::vector'
3:
4: array_view<int, 1> arrViewSum(M); // Creation of array_view without data resource
5:
6: parallel_for_each(arrViewSum.extent, [=](const index<1> &idx) restrict(amp) {
7: arrViewSum[idx] = arrViewA[idx] + arrViewB[idx];
8: });
9:
10: for (size_t i = 0; i < arrViewSum.extent.size(); ++i) {
11: arrViewSum.data[i]; // Accessing the result of computation
12: }
It is vividly evident that ‘array_view without data source’ is simple to use and in deed resulted in fewer lines of code :-)
In Closing
In this post we looked at the one of the improvements we’ve made to Array_views in Visual Studio 2013. Stay tuned for more blog posts on the improvements of C++ AMP in Visual Studio 2013. As usual, I would love to read your comments below or in our MSDN forum.
Comments
- Anonymous
April 10, 2014
Is it possible to create array_view without data source in VS 2012 with any patch? I have a situation in my code that i have to get data on device without using array as if i create array i have to do it dynamically an then free it which is not possible as pointers are not allowed inside parallel_foreach. i am working with class which has array_view as data member .