从具有不同分配器的 stl 容器构建是否可以?
is it ok to construct from a stl container which has a different allocator?
说我有
std::vector<T, allocator1=default allocator in STL> A
std::vector<T, allocator2=some other allocator> B
我在 Cilk Plus 中使用 __offload::shared_allocator 作为分配器 2,用于从主机 CPU 卸载到 Xeon Phi 协处理器
我可以从 B 构造 A 吗?
std::vector<T> A{B.begin(), B.end()};
更一般地说,不同的分配器对哪种 STL 函数很重要?
如评论中所述,构造函数
std::vector<T> A{B.begin(), B.end()};
应该可以正常工作,因为它适用于任何两个迭代器。至于"for which kind of STL functions that different allocators will matter?"这个问题,有两种"different":
- 不同类型的分配器。
- 分配器类型相同,但比较不同。
对于 (1) 的不兼容性,您应该会看到一个编译时错误,因为类型系统会捕获它。对于 (2),我不知道 STL 实现是否捕获了可能的问题。在这方面,主要 container/function 担心的是 class list
上的 splice
方法(以及 class [=16= 上的 splice_after
方法]), 因为它们将分配在一个容器中的对象移动到另一个容器中。正如 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
说我有
std::vector<T, allocator1=default allocator in STL> A
std::vector<T, allocator2=some other allocator> B
我在 Cilk Plus 中使用 __offload::shared_allocator 作为分配器 2,用于从主机 CPU 卸载到 Xeon Phi 协处理器
我可以从 B 构造 A 吗?
std::vector<T> A{B.begin(), B.end()};
更一般地说,不同的分配器对哪种 STL 函数很重要?
如评论中所述,构造函数
std::vector<T> A{B.begin(), B.end()};
应该可以正常工作,因为它适用于任何两个迭代器。至于"for which kind of STL functions that different allocators will matter?"这个问题,有两种"different":
- 不同类型的分配器。
- 分配器类型相同,但比较不同。
对于 (1) 的不兼容性,您应该会看到一个编译时错误,因为类型系统会捕获它。对于 (2),我不知道 STL 实现是否捕获了可能的问题。在这方面,主要 container/function 担心的是 class list
上的 splice
方法(以及 class [=16= 上的 splice_after
方法]), 因为它们将分配在一个容器中的对象移动到另一个容器中。正如 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