C++ Amp로 응용 프로그램을 최적화하려고 할 때 다음과 같은 문제가 발생했습니다. 데이터가 전송됩니다. 나에게는 CPU에서 GPU로 데이터를 복사하는 데 문제가 없다 (애플리케이션의 초기 상태에서 할 수있는 것처럼). 더 나쁜 것은 C++ Amp 커널에 의해 계산 된 결과에 대한 빠른 액세스가 필요하기 때문에 GPU와 CPU 간의 병목 현상이 발생하는 것입니다. Windows 8.1에서 성능이 향상되었지만 Windows 7을 사용하고 있으며이를 변경하려고하지는 않습니다. 스테이징 어레이에 대해서는 읽었지만 어떻게 문제를 해결할 수 있을지 모르겠습니다. 호스트에 단일 부동 소수점 값을 반환해야하며 시간이 많이 소요되는 작업 인 것으로 보입니다. C++ Amp에서 GPU-CPU 데이터 전송 감소
float Subset::reduction_cascade(unsigned element_count, concurrency::array<float, 1>& a)
{
static_assert(_tile_count > 0, "Tile count must be positive!");
//static_assert(IS_POWER_OF_2(_tile_size), "Tile size must be a positive integer power of two!");
assert(source.size() <= UINT_MAX);
//unsigned element_count = static_cast<unsigned>(source.size());
assert(element_count != 0); // Cannot reduce an empty sequence.
unsigned stride = _tile_size * _tile_count * 2;
// Reduce tail elements.
float tail_sum = 0.f;
unsigned tail_length = element_count % stride;
// Using arrays as a temporary memory.
//concurrency::array<float, 1> a(element_count, source.begin());
concurrency::array<float, 1> a_partial_result(_tile_count);
concurrency::parallel_for_each(concurrency::extent<1>(_tile_count * _tile_size).tile<_tile_size>(), [=, &a, &a_partial_result] (concurrency::tiled_index<_tile_size> tidx) restrict(amp)
{
// Use tile_static as a scratchpad memory.
tile_static float tile_data[_tile_size];
unsigned local_idx = tidx.local[0];
// Reduce data strides of twice the tile size into tile_static memory.
unsigned input_idx = (tidx.tile[0] * 2 * _tile_size) + local_idx;
tile_data[local_idx] = 0;
do
{
tile_data[local_idx] += a[input_idx] + a[input_idx + _tile_size];
input_idx += stride;
} while (input_idx < element_count);
tidx.barrier.wait();
// Reduce to the tile result using multiple threads.
for (unsigned stride = _tile_size/2; stride > 0; stride /= 2)
{
if (local_idx < stride)
{
tile_data[local_idx] += tile_data[local_idx + stride];
}
tidx.barrier.wait();
}
// Store the tile result in the global memory.
if (local_idx == 0)
{
a_partial_result[tidx.tile[0]] = tile_data[0];
}
});
// Reduce results from all tiles on the CPU.
std::vector<float> v_partial_result(_tile_count);
copy(a_partial_result, v_partial_result.begin());
return std::accumulate(v_partial_result.begin(), v_partial_result.end(), tail_sum);
}
내가 가장 시간이 많이 걸리는 작업 위의 예에서
copy(a_partial_result, v_partial_result.begin());
것을 확인. 나는 더 나은 접근법을 찾고있다.
데이터 복사본과 코드의 계산 부분을 어떻게 타이밍을 맞추고 계십니까? C++ AMP 호출은 비동기식이며, DMA 버퍼에 항목을 대기시키고 필요한 경우에만 차단합니다. 타이밍에 대한 자세한 내용은 다음 답변을 참조하십시오. http://stackoverflow.com/questions/13936994/copy-data-from-gpu-to-cpu/14013053#14013053 –
타이밍이 같아 타이밍이 맞지 않습니다. -parrallel 방법. copy() 메소드를 주석 처리했을 때, 800-900 ms에서 300 ms까지 증가했다. –
@up 복사 기능을 주석 처리 할 때 <200ms가됩니다. –