2015-04-12 2 views
0

Скажем, у меня естьМожно ли построить из контейнера stl, который имеет другой распределитель?

std::vector<T, allocator1=default allocator in STL> A 

std::vector<T, allocator2=some other allocator> B 

Я использую __offload :: shared_allocator в allocator2 в Cilk Plus для разгрузки от хост-процессора для Xeon Phi сопроцессора

Могу ли я построить от B?

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

И более общий, для каких функций STL, которые будут иметь разные распределители?

+3

Это не конструктор копирования вы звоните. –

+0

Хорошо, извините ... Я изменю заголовок – yidiyidawu

+0

Пока они не являются тривиальными указателями, это не 'std :: vector > :: iterator' другой тип, чем' std: : vector > :: iterator'? –

ответ

0

Как было отмечено в комментариях, конструктор

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

должен работать хорошо, так как он работает для любых двух итераторов. Что касается вопроса «для каких функций STL, которые могут иметь разные распределители?», Существует два типа «разных»:

  1. Абонентские блоки разных типов.
  2. Распределители того же типа, но сравниваются как разные.

Для несовместимости по отношению к (1) вы должны увидеть ошибку времени компиляции, потому что система типа поймает ее. Для (2) я не знаю, поймут ли реализации STL возможные проблемы или нет. Основным контейнером/функцией, о которой нужно беспокоиться в этом отношении, являются методы splice класса listsplice_after методов класса forward_list), поскольку они перемещают объект, выделенный в одном контейнере, в другой контейнер. Как примечание 265 стандартных заметок C++ 11, контейнеры 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 
+0

Итак, с точки зрения C++ все в порядке. Но с точки зрения сопроцессора Intel Xeon Phi - вы используете B в области разгрузки, но как насчет A?Мне нужно много узнать о том, как использовать C++ с кодом разгрузки, поэтому я могу быть мокрым, но я не верю, что A можно использовать в области разгрузки и в первый раз, когда вы использовали распределитель в A, до B, насколько это используется в разгруженном коде? – froth

+0

Я расширил свой ответ, чтобы попытаться ответить на этот вопрос. –

+0

Но если A построено на сопроцессоре, и вы вставляете элемент в A, что произойдет, если вы будете перебирать B на стороне хоста? Разве это не отправит вас в сорняки? – froth

Смежные вопросы