0

说我有

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 函数很重要?

4

1 回答 1

0

如评论中所述,构造函数

std::vector<T> A{B.begin(), B.end()};

应该可以正常工作,因为它适用于任何两个迭代器。至于“不同的分配器对哪种 STL 函数有影响?”的问题,有两种“不同”:

  1. 具有不同类型的分配器。
  2. 具有相同类型但比较不同的分配器。

对于与 (1) 的不兼容性,您应该会看到编译时错误,因为类型系统会捕获它。对于 (2),我不知道 STL 实现是否捕捉到可能的问题。在这方面要担心的主要容器/功能是类上的splice方法list(和splice_after类上的方法forward_list),因为它们将分配在一个容器中的对象移动到另一个容器。作为 C++11 标准注释的脚注 265,STL 容器要求分配器比较相等,因此这样的移动应该不是问题。

关于卸载问题,如果 A 被分配了一个普通的 STL 分配器,那么它就不能在主机端构建并在协处理器端使用。但是B可以在两边都使用。这是一个在协处理器端从中构造 B using anoffload::shared_allocator A` 的示例。, and constructs

#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
于 2015-04-13T15:28:01.213 回答