3

C++ AMP コードの記述に問題があります。サンプルを入れました。エミュレートされたアクセラレータでは正常に動作しますが、ハードウェア (Windows 7、NVIDIA GeForce GTX 660、最新のドライバー) ではディスプレイ ドライバーがクラッシュしますが、コードに問題はありません。

私のコードに問題がありますか、それともハードウェア/ドライバー/コンパイラーの問題ですか?

#include "stdafx.h"

#include <vector>
#include <iostream>
#include <amp.h>

int _tmain(int argc, _TCHAR* argv[])
{
    // Prints "NVIDIA GeForce GTX 660"
    concurrency::accelerator_view target_view = concurrency::accelerator().create_view();
    std::wcout << target_view.accelerator.description << std::endl;

    // lower numbers do not cause the issue
    const int x = 2000;
    const int y = 30000;

    // 1d array for storing result
    std::vector<unsigned int> resultVector(y);
    Concurrency::array_view<unsigned int, 1> resultsArrayView(resultVector.size(), resultVector);

    // 2d array for data for processing 
    std::vector<unsigned int> dataVector(x * y);
    concurrency::array_view<unsigned int, 2> dataArrayView(y, x, dataVector);
    parallel_for_each(
        // Define the compute domain, which is the set of threads that are created.
        resultsArrayView.extent,
        // Define the code to run on each thread on the accelerator.
        [=](concurrency::index<1> idx) restrict(amp)
    {
        concurrency::array_view<unsigned int, 1> buffer = dataArrayView[idx[0]];
        unsigned int bufferSize = buffer.get_extent().size();

        // needs both loops to cause crash
        for (unsigned int outer = 0; outer < bufferSize; outer++)
        {
            for (unsigned int i = 0; i < bufferSize; i++)
            {
                // works without this line, also if I change to buffer[0] it works?
                dataArrayView[idx[0]][0] = 0;
            }
        }
        // works without this line
        resultsArrayView[0] = 0;
    });

    std::cout << "chash on next line" << std::endl; 
    resultsArrayView.synchronize();
    std::cout << "will never reach me" << std::endl; 

    system("PAUSE");
    return 0;
}
4

1 に答える 1

8

計算が許容量子時間(デフォルトは2秒)を超えている可能性が非常に高いです。その後、オペレーティングシステムが起動し、GPUを強制的に再起動します。これは、タイムアウト検出および回復(TDR)と呼ばれます。ソフトウェアアダプタ(参照デバイス)でTDRが有効になっていないため、計算が許容量子時間を超える可能性があります。

あなたの計算は本当に3000スレッド(変数x)を必要とし、それぞれが2000 * 3000(x * y)ループ反復を実行しますか?各チャンクの計算に2秒もかからないように、計算をチャンク化できます。ニーズに合わせて、TDRを無効にするか、許可されたクォンタム時間を超過することも検討できます。

TDRを詳細に説明しているC++AMPでのTDRの処理方法に関するブログ投稿を読むことを強くお勧めします:http://blogs.msdn.com/b/nativeconcurrency/archive/2012/03/07/handling-tdrs-in- c-amp.aspx

さらに、Windows 8でTDRを無効にする方法に関する別のブログ投稿があります:http: //blogs.msdn.com/b/nativeconcurrency/archive/2012/03/06/disabling-tdr-on-windows-8- for-your-c-amp-algorithms.aspx

于 2013-03-14T21:39:20.920 に答える