Скажи у меня
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
Могу ли я построить А из Б?
std::vector<T> A{B.begin(), B.end()};
И, в общем, для каких функций STL будут важны разные распределители?
Как отмечено в комментариях, конструктор
std::vector<T> A{B.begin(), B.end()};
должно работать нормально, так как оно работает для любых двух итераторов. Что касается вопроса «для каких функций STL будут важны разные распределители?», Существует два вида «разных»:
Для несовместимости относительно (1), вы должны увидеть ошибку во время компиляции, потому что система типов поймает ее. Для (2) я не знаю, улавливают ли реализации STL возможные проблемы или нет. Основным контейнером / функцией, о котором следует беспокоиться, являются splice
методы на уроке list
(а также splice_after
методы на уроке forward_list
), поскольку они перемещают объект, размещенный в одном контейнере, в другой контейнер. Как отмечается в сноске 265 стандарта C ++ 11, контейнеры STL требуют, чтобы распределители сравнивались одинаково, поэтому такое перемещение не должно быть проблемой.
Что касается проблем разгрузки, если A выделяется с простым распределителем STL, то он не может быть создан на стороне хоста и использован на стороне сопроцессора. Но B можно использовать с обеих сторон. Вот пример, который строит B using an
разгружать :: shared_allocator, 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