说我有
std::vector<T, allocator1=default allocator in STL> A
std::vector<T, allocator2=some other allocator> B
我在Cilk Plus中使用__offload :: shared_allocator作为allocator2,用于从主机CPU卸载到Xeon Phi协处理器
我可以从B构建A吗?
std::vector<T> A{B.begin(), B.end()};
更一般地说,不同分配器对哪种STL函数有用?
答案 0 :(得分:0)
如评论中所述,构造函数
std::vector<T> A{B.begin(), B.end()};
应该可以正常工作,因为它适用于任何两个迭代器。至于“不同分配器将关注哪种STL功能?”的问题,有两种“不同”:
对于与(1)的不兼容性,您应该看到编译时错误,因为类型系统将捕获它。对于(2),我不知道STL实现是否捕获了可能的问题。在这方面需要担心的主要容器/函数是类splice
上的list
方法(以及类splice_after
上的forward_list
方法),因为它们移动了一个分配的对象一个容器到另一个容器。正如C ++ 11标准的脚注265所述,STL容器要求分配器比较相等,因此这种移动应该不是问题。
关于卸载问题,如果A分配有普通STL分配器,则它不能在主机端构建并在协处理器端使用。但B可以用于双方。这是一个在协处理器端从它构造B using an
offload :: shared_allocator , and constructs
A`的示例。
#pragma offload_attribute (push, _Cilk_shared)
#include <vector>
#include "offload.h"
#include <cstdio>
#pragma offload_attribute (pop)
_Cilk_shared std::vector<int, __offload::shared_allocator<int> > B;
_Cilk_shared void foo() {
#ifdef __MIC__
std::vector<int> A(B.begin(),B.end());
for( auto& x: A )
std::printf("%d\n", x);
#else
std::printf("Host\n");
#endif
}
int main() {
auto y = 1;
for( int i=0; i<10; ++i ) {
B.push_back(y);
y *= 10;
}
_Cilk_offload foo();
}
应该打印:
1
10
100
1000
10000
100000
1000000
10000000
100000000
1000000000