【问题标题】:is it ok to construct from a stl container which has a different allocator?可以从具有不同分配器的 stl 容器构造吗?
【发布时间】:2015-04-12 22:15:49
【问题描述】:

说我有

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

【问题讨论】:

  • 你调用的不是拷贝构造函数。
  • 好吧对不起...我会改标题
  • 只要它们不是微不足道的指针,std::vector&lt;T, std::allocator&lt;T&gt;&gt;::iterator 不是与std::vector&lt;T, __offload::shared_allocator&lt;T&gt;&gt;::iterator 不同的类型吗?
  • @nabijaczleweli 没关系(如果迭代器是 SCARY,它们也不需要),双迭代器构造函数接受所有输入迭代器。
  • @T.C.刚查了一下,你是对的。我是个白痴/正在考虑别的事情,对不起。

标签: c++ stl allocation xeon-phi cilk-plus


【解决方案1】:

如 cmets 中所述,构造函数

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

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

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

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

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

#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

【讨论】:

  • 所以,从 C++ 的角度来看,一切都很好。但从英特尔至强融核协处理器的角度来看 - 您在卸载区域中使用 B,但 A 呢?关于将 C++ 与卸载代码一起使用,我有很多东西要学习,所以我可能全都湿透了,但我不相信 A 可以在卸载区域中使用,而且当你第一次在 A 中使用分配器时,你不会搞砸就在卸载代码中使用它而言,最多 B 吗?
  • 但是如果A是在协处理器上构造的,并且你在A中插入一个元素,如果你在主机端迭代B会发生什么?它不会让你陷入困境吗?
  • A 是用 B 中的元素的副本构建的。更改 A 对 B 没有影响,反之亦然,在构建 A 之后。
  • 谢谢,,..这个例子很有帮助
  • 如果它们有不同的分配器,我基本上不能移动构造新对象吗?
猜你喜欢
  • 2021-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-15
  • 2019-05-06
  • 1970-01-01
  • 1970-01-01
  • 2013-09-19
相关资源
最近更新 更多