Aracılığıyla paylaş


İzlenecek yol: C++ amp uygulama hata ayıklama

Bu konu, grafik işlemci birimi (gpu) yararlanmak için C++ hızlandırılmış yekpare paralellik (C++ amp) kullanan bir uygulamada nasıl hata ayıklanacağını gösterir.Büyük bir dizi tamsayının toplamını alan bir paralel azaltma programı kullanır.Bu örneklerde aşağıdaki görevler gösterilir:

  • gpu hata ayıklayıcısını başlatma.

  • gpu iş parçacığı penceresinde gpu iş parçacıklarını inceleme.

  • Aynı anda birden çok gpu iş parçacığı çağrı yığınını gözlemlemek için paralel yığınları penceresini kullanma.

  • Aynı anda birden çok iş parçacığı üzerindeki tek bir ifadenin değerini incelemek için paralel Gözcü penceresi kullanma.

  • Bayrak atama, dondurma, çözülme ve gpu iş parçacığı gruplandırma.

  • Kod içinde belirli bir konumda bir döşemenin tüm iş parçacıklarını yürütme.

Önkoşullar

Bu tam çözüme başlamadan önce:

[!NOT]

Bilgisayarınızda, aşağıdaki yönergelerde yer alan Visual Studio kullanıcı arabirimi öğelerinden bazılarının adı veya konumu farklı gösterilebilir. Bu öğeleri bilgisayarınızdaki Visual Studio sürümü ve kullandığınız ayarlar belirler. Daha fazla bilgi için bkz: Visual Studio ayarları.

Örnek Proje oluşturmak için

  1. Visual &Studio'yu başlatın.

  2. Menü çubuğunda File, Yeni, Proje 'yi seçin.

  3. Yüklü altındaki şablonlar bölmesinde Visual C++ 'ı seçin.

  4. Bir Win32 konsol uygulamasıseçin, AMPMapReduce olarakta kutunun adını yazın,ve sonra Tamam düğmesine basın.

  5. İleri düğmesini seçin.

  6. Önce derlemeden önceki başlığı temizleyin ve sonra da Son düğmesini seçin.

  7. Solution Explorer'da, stdafx.h, targetver.h ve stdafx.cpp dosyalarını projeden silin.

  8. AMPMapReduce.cpp'yi açın ve içeriğini aşağıdaki kodla değiştirin.

    // AMPMapReduce.cpp defines the entry point for the program.
    // The program performs a parallel-sum reduction that computes the sum of an array of integers. 
    
    #include <stdio.h>
    #include <tchar.h>
    #include <amp.h>
    
    const int BLOCK_DIM = 32;
    
    using namespace concurrency;
    
    void sum_kernel_tiled(tiled_index<BLOCK_DIM> t_idx, array<int, 1> &A, int stride_size) restrict(amp)
    {
        tile_static int localA[BLOCK_DIM];
    
        index<1> globalIdx = t_idx.global * stride_size;
        index<1> localIdx = t_idx.local;
    
        localA[localIdx[0]] =  A[globalIdx];
    
        t_idx.barrier.wait();
    
        // Aggregate all elements in one tile into the first element.
        for (int i = BLOCK_DIM / 2; i > 0; i /= 2) 
        {
            if (localIdx[0] < i) 
            {
    
                localA[localIdx[0]] += localA[localIdx[0] + i];
            }
    
            t_idx.barrier.wait();
        }
    
        if (localIdx[0] == 0)
        {
            A[globalIdx] = localA[0];
        }
    }
    
    int size_after_padding(int n)
    {
        // The extent might have to be slightly bigger than num_stride to 
        // be evenly divisible by BLOCK_DIM. You can do this by padding with zeros.
        // The calculation to do this is BLOCK_DIM * ceil(n / BLOCK_DIM)
        return ((n - 1) / BLOCK_DIM + 1) * BLOCK_DIM;
    }
    
    int reduction_sum_gpu_kernel(array<int, 1> input) 
    {
        int len = input.extent[0];
    
        //Tree-based reduction control that uses the CPU.
        for (int stride_size = 1; stride_size < len; stride_size *= BLOCK_DIM) 
        {
            // Number of useful values in the array, given the current
            // stride size.
            int num_strides = len / stride_size;  
    
            extent<1> e(size_after_padding(num_strides));
    
            // The sum kernel that uses the GPU.
            parallel_for_each(extent<1>(e).tile<BLOCK_DIM>(), [&input, stride_size] (tiled_index<BLOCK_DIM> idx) restrict(amp)
            {
                sum_kernel_tiled(idx, input, stride_size);
            });
        }
    
        array_view<int, 1> output = input.section(extent<1>(1));
        return output[0];
    }
    
    int cpu_sum(const std::vector<int> &arr) {
        int sum = 0;
        for (size_t i = 0; i < arr.size(); i++) {
            sum += arr[i];
        }
        return sum;
    }
    
    std::vector<int> rand_vector(unsigned int size) {
        srand(2011);
    
        std::vector<int> vec(size);
        for (size_t i = 0; i < size; i++) {
            vec[i] = rand();
        }
        return vec;
    }
    
    array<int, 1> vector_to_array(const std::vector<int> &vec) {
        array<int, 1> arr(vec.size());
        copy(vec.begin(), vec.end(), arr);
        return arr;
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        std::vector<int> vec = rand_vector(10000);
        array<int, 1> arr = vector_to_array(vec);
    
        int expected = cpu_sum(vec);
        int actual = reduction_sum_gpu_kernel(arr);
    
        bool passed = (expected == actual);
        if (!passed) {
            printf("Actual (GPU): %d, Expected (CPU): %d", actual, expected);
        }
        printf("sum: %s\n", passed ? "Passed!" : "Failed!"); 
    
        getchar();
    
        return 0;
    }
    
  9. Menü çubuğunda, Dosya, Tümünü Kaydet'i seçin.

  10. Solution Explorer'da AMPMapReduce kısayol menüsünü açın ve sonra Özellikleri seçin.

  11. Özellik Sayfaları iletişim kutusunda, Görünüm Özellikleri 'nin altında, c/C++, Ön derleme başlıkları 'ni seçin.

  12. Ön derleme başlığı özelliği için, Ön derleme başlıkları kullanmamak' seçin ve sonra Tamam düğmesini seçin.

  13. Menü çubuğunda Oluştur, Çözüm oluştur 'u seçin.

cpu kodda hata ayıklama

Bu yöntemde, bu uygulamada cpu kodunun doğru olduğundan emin olmak için Yerel Windows Hata Ayıklayıcı'yı kullanacaksınız.Bu uygulamanın cpu kodundaki ilginç olan kesimi for döngülerinden reduction_sum_gpu_kernel fonksiyonu içerisinde olanıdır.gpu üzerinde çalışan ağaç tabanlı paralel azaltmayı kotrol eder.

cpu kodda hata ayıklamak

  1. Solution Explorer'da AMPMapReduce kısayol menüsünü açın ve sonra Özellikleri seçin.

  2. Özellik Sayfaları iletişim kutusunda, Görünüm Özellikleri'nin altında, Hata Ayıklama'yı seçin.Yerel Windows hata ayıklayıcı 'nın başlatılacak hata ayıklayıcı listesinde seçili olduğunu doğrulayın.

  3. Kod Düzenleyicisi'ne geri dönün.

  4. Aşağıdaki çizimde gösterilen kod satırlarında kesme noktaları ayarlayın (yaklaşık satır 67 satır 70).

    CPU Kesme Noktaları

    CPU kesme noktaları

  5. Menü çubuğunda Hata Ayıklayıcı, Hata Ayıklamaya başla'yı seçin.

  6. Yereller penceresinde, 70 satırındaki kesme noktasına ulaşılana dek stride_size değerini gözlemleyin.

  7. Menü çubuğunda Hata Ayıklama, Hata Ayıklamayı durdur'u seçin.

gpu kodda hata ayıklama

Bu bölüm , sum_kernel_tiled fonksiyonu içinde bulunan kod olan GPU koda nasıl hata ayıklama yapılacağını gösterir.gpu kod paralel olarak her "blok" için tamsayıların toplamını hesaplar.

gpu kodda hata ayıklamak

  1. Solution Explorer'da AMPMapReduce kısayol menüsünü açın ve sonra Özellikleri seçin.

  2. Özellik Sayfaları iletişim kutusunda, Görünüm Özellikleri'nin altında, Hata Ayıklama'yı seçin.

  3. Başlatılacak Hata ayıklayıcı listesi içinde , Yerel Windows hata ayıklayıcı'yı seçin.

  4. Hata ayıklayıcı türü listesi içinde , Sadece gpu'yu seçin.

  5. Tamam düğmesini seçin.

  6. Aşağıdaki çizimde gösterildiği gibi,satır 30'da bir kesme noktası ayarlayın.

    GPU Kesme Noktası

    GPU kesme noktaları

  7. Menü çubuğunda Hata Ayıklayıcı, Hata Ayıklamaya başla'yı seçin.CPU koddaki 67 ve 70 satırlarında yer alan kesme noktaları GPU hata ayıklaması sırasında çalıştırılmaz çünkü bu kod satırları CPU'da çalıştırılır.

gpu iş parçacıkları penceresini kullanmak

  1. gpu iş parçacıkları penceresini açmak için menü çubuğunda Hata Ayıklama, Pencereler, gpu iş parçacıkları'nı seçin.

    Görünen gpu iş parçacıkları penceresinde gpu iş parçacıkları durumunu inceleyebilirsiniz.

  2. gpu iş parçacıkları penceresini Visual Studio'nun altına sabitleyin.iş parçacığı geçişini genişlet düğmesini döşeme ve iş parçacığı metin kutularını görüntülemek için seçin.gpu iş parçacıkları penceresi, aşağıdaki çizimde gösterildiği gibi etkin ve engellenen gpu iş parçacıklarının toplam sayısını gösterilir.

    İş Parçacıkları Penceresi

    Etkin iş parçacıkları 4 GPU iş parçacığı penceresi

    Bu hesaplama işlemi için ayrılan 313 döşeme vardır.Her döşeme 32 iş parçacığı içerir.Yerel GPU hata ayıklama yazılım emülatörü üzerinde gerçekleştiği için dört etkin gpu iş parçacığı vardır.Dört iş parçacığı yönergeleri aynı anda çalıştırır ve daha sonra birlikte bir sonraki yönergeye ilerlerler.

    gpu iş parçacıkları penceresinde tile_barrier::wait deyiminde, satır 21'de tanımlanmıştır (t_idx.barrier.wait();), dört etkin gpu iş parçacığı ve 28 engelli gpu iş parçacığı vardır.32 gpu iş parçacığının tümü ilk döşemeye, tile[0]'a aittir.Ok, geçerli iş parçacığı içeren satıra işaret eder.Farklı bir iş parçacığına geçiş yapmak için aşağıdaki yöntemlerden birini kullanın:

    • gpu iş parçacıkları penceresinde iş parçacığının satıra geçiş yapması için kısayol menüsünü açın ve İş parçacığına geç'i seçin.Satır birden çok iş parçacığını temsil ediyorsa, iş parçacığı koordinatlarına göre ilk iş parçacığına geçeceksiniz.

    • Döşeme ve iş parçacığı değerlerini karşılık gelen metin kutularına girin ve sonra iş parçacığı değiştir düğmesini seçin.

    Çağrı yığını penceresi, geçerli gpu iş parçacığının çağrı yığınını görüntüler.

Paralel yığınlar penceresini kullanmak

  1. Paralel yığınlar penceresini açmak için menü çubuğunda Hata Ayıklama, Pencereler, Paralel yığınlar'ı seçin.

    Aynı anda birden çok gpu iş parçacığı yığınının çerçevelerini incelemek için paralel yığınlar penceresini kullanabilirsiniz.

  2. Paralel yığınlar penceresinin Visual Studio'nun alt kısmına sabitleyin.

  3. iş parçacıkları 'nın sol üst köşesindeki listede seçili olduğundan emin olun.Aşağıdaki çizimde, paralel yığınlar penceresi gpu iş parçacıkları penceresinde gördüğünüz gpu iş parçacığı çağrı yığını odaklanmış görünümünü gösterir.

    Paralel yığınlar penceresi

    4 Etkin iş parçacıkları ile Paralel Yığınlar penceresi

    32 iş parçacığı _kernel_stub 'tan, parallel_for_each fonksiyon çağrısındaki lambda deyimine ve daha sonra paralel azaltmanın oluştuğu sum_kernel_tiled fonksiyonuna gitti.32 iş parçacığından 28'i tile_barrier::wait deyimine ilerleyip satır 22'de engellenmiş olarak kalmaya devam ederken, diğer4 iş parçacığı sum_kernel_tiled fonksiyonun satır 30'da aktif olarak kalır.

    aralel yığınlar penceresinin Zengin DataTip 'inde gpu iş parçacığı penceresinde bulunabilen gpu iş parçacığının özelliklerini inceleyebilirsiniz.Bunu yapmak için fare işaretçisini sum_kernel_tiled'ın yığın çerçevesi üzerinde bekletin.DataTip aşağıda gösterilmiştir.

    gpu iş parçacığı DataTip

    DataTip Paralel Yığınlar penceresi

    Paralel yığınlar penceresi hakkında daha fazla bilgi için bkz: Paralel yığınları penceresini kullanma.

Paralel Gözcü penceresini kullanmak

  1. Paralel Gözcü penceresini açmak için menü çubuğunda Hata Ayıklama, Pencereler, Paralel gözlem, paralel Watch 1'i seçin.

    Birden çok iş parçacığı üzerinde bir ifadenin değerlerini incelemek için paralel Gözcü penceresini kullanabilirsiniz.

  2. Paralel Watch 1 penceresini Visual Studio'nun alt kesimine sabitleyin.Paralel Gözcü penceresi tablosunda 32 satır vardır.Her biri gpu iş parçacığı penceresinde ve paralel yığınlar penceresinde görünen bir gpu iş parçacığına karşılık gelir.Şimdi, tüm 32 gpu parçacıkları arasında değerlerini incelemek istediğiniz ifadeleri girebilirsiniz.

  3. Gözcü ekle sütun başlığını seçin, localIdx'yi girin ve sonra da Enter tuşunu seçin.

  4. Gözcü ekle sütun başlığını yeniden seçin, globalIdx'yi yazın ve sonra da Enter tuşunu seçin.

  5. Gözcü ekle sütun başlığını yeniden seçin, localA[localIdx [0]'ı yazın ve sonra da Enter tuşunu seçin.

    Karşılık gelen sütun başlığını seçerek belirtilen bir ifadeye göre sıralayabilirsiniz.

    localA[localIdx [0] sütun başlığını sütunu sıralamak için seçin.Aşağıdaki çizim localA[localIdx [0]'a göre sıralama sonuçlarını gösterir.

    Sıralama sonuçları

    Sıralanmış sonuçları ile paralel Gözcü penceresi

    Paralel Gözcü penceresindeki içeriği Excel düğmesini seçerek ve sonra Excel'de Aç'ı seçerek Excel'e verebilirsiniz.Geliştirme bilgisayarınızda Excel yüklü ise, bu, içeriği içeren bir Excel çalışma sayfasını açar.

  6. Paralel İzleme penceresinin sağ üst köşesinde içeriği Boole ifadeleri kullanarak filtreleme için kullanabileceğiniz bir filtre denetimi vardır.Filtre control metin kutusuna localA[localIdx [0]] > 20000 girin ve sonra Enter tuşunu seçin.

    Pencere artık yalnızca localA[localIdx[0]] değeri 20000'den büyük olan iş parçacıklarını içerir.İçerik daha önce gerçekleştirilen sıralama eylemi olan localA[localIdx[0]] sütununa göre sıralıdır.

gpu iş parçacıklarına bayrak atama

Belirli gpu iş parçacığını gpu iş parçacıkları penceresi, paralel Gözcü penceresi veya paralel yığınlar penceresindeki DataTip'te bayrak atama yaparak işaretleyebilirsiniz.gpu iş parçacığı penceresinde bir satır birden çok iş parçacığı içeriyorsa, satıra bayrak eklemek satırda bulunan tüm iş parçacıklarını bayraklar.

gpu iş parçacıklarını Bayraklamak

  1. Paralel Watch 1 penceresindeki [iş parçacığı] sütun başlığını döşeme dizinine ve iş parçacığı dizinine göre sıralamak için seçin.

  2. Menü çubuğunda Hata ayıklama, Devam'ı seçmek , etkin dört iş parçacığının sonraki engele (AMPMapReduce.cpp'de satır 32 tanımlanan) ilerlemesine sebep olur.

  3. Artık etkin olan dört iş parçacığını içeren satırın sol tarafındaki Bayrak simgesini seçin.

    Aşağıdaki resimde dört etkin bayraklı iş parçacığı, gpu iş parçacıkları penceresi içinde gösterilir.

    gpu iş parçacıkları penceresindeki etkin iş parçacıkları

    Bayraklı iş parçacıkları ile GPU iş parçacığı penceresi

    Paralel Gözcü penceresi ve paralel yığınlar pencerenin DataTip'i, her ikisi de bayraklı iş parçacıklarını gösterir.

  4. Bayrakladığınız dört iş parçacığı üzerinde odaklanmak istiyorsanız, gpu iş parçacıkları, Paralel Gözcü ve paralel yığınlar pencerelerinde sadece bayraklı iş parçacıklarını görüntülemeyi seçebilirsiniz.

    Herhangi bir penceredeki veya Hata ayıklama konumu araç çubuğundaki Yalnızca Bayraklıları Göster düğmesini seçin.Aşağıdaki resim Hata ayıklama konumu araç çubuğundaki Sadece bayraklıları Göster düğmesini gösterir.

    Yalnızca bayraklıları göster düğmesi

    Konum araç çubuğunu göster yalnızca bayrak simgesi ile hata ayıklama

    Şimdi gpu iş parçacıkları, paralel gözcü ve paralel yığınlar pencereleri sadece bayraklı iş parçacıklarını görüntüler.

Dondurma ve çözme gpu iş parçacıkları

GPU iş parçacıklarını gpu iş parçacıklarıı penceresinden veya paralel Gözcü penceresinden dondurabilir (askıya almak) ve çözebilirsiniz (sürdürmek).CPU iş parçacıklarını da aynı şekilde dondurabilir ve çözebilirsiniz; bilgi için bkz: Nasıl yapılır: iş parçacığı penceresini kullanma.

GPU iş parçacıkları dondurma ve çözme

  1. Tüm iş parçacıklarını görüntülemek için Sadece Bayraklıları Göster düğmesini seçin.

  2. Menü çubuğunda Hata Ayıklama, Devam'ı seçin.

  3. Etkin satır için kısayol menüsünü açın ve sonra Dondurma'yı seçin.

    Aşağıdaki gpu iş parçacıkları penceresi resmi tüm dört iş parçacığının dondurulmuş olduğunu göstermektedir.

    gpu iş parçacıkları penceresinde dondurulmuş iş parçacıkları

    Dondurulmuş iş parçacıklarını gösteren GPU iş parçacığı windows

    Benzer şekilde, paralel Gözcü penceresi tüm dört iş parçacığının dondurulmuş olduğunu gösterir.

  4. Menü çubuğunda Hata Ayıklama, Devam 'ı sonraki dört gpu iş parçacığının satır 22'deki engeli aşmasına ve satır 30'daki kesme hattına ulaşmasına izin vermek için seçin.gpu iş parçacıkları penceresi önceden dondurulmuş dört iş parçacığının dondurulmuş kaldığını ve etkin durumda olduğunu gösterir.

  5. Menü çubuğunda Hata Ayıklama, Devam'ı seçin.

  6. Paralel Gözcü penceresinden tek tek veya birden çok gpu iş parçacığını çözebilirsinizde.

gpu iş parçacıklarını gruplandırmak

  1. Kısayol menüsünde gpu iş parçacıkları penceresindeki iş parçacıklarından biri için, Grupla, Adres'i seçin.

    gpu iş parçacıkları penceresindeki iş parçacıkları adrese göre gruplandırılır.Adres her iş parçacığı grubunun bulunduğu dağılımdaki yönergesine karşılık gelir.24 iş parçacığı tile_barrier::Wait yöntemi 'ın yürütüldüğü yerde,satır 22'dedir.12 iş parçacığı satır 32'deki engelin yönergesindedir.Bu iş parçacıklarından dörtü bayraklanmıştır.Sekiz iş parçacığı satır 30'daki kesme noktasındadır.Bu iş parçacıklarından dörtü dondurulmuştur.Aşağıdaki resim gpu iş parçacığı penceresi içinde gruplandırılmış iş parçacıklarını gösterir.

    gpu iş parçacığı penceresindeki gruplandırılmış iş parçacıkları

    Adresine göre gruplandırılmış iş parçacıklarıyla GPU iş parçacığı penceresi

  2. Grupla işlemini kısayol menüsünü Paralel gözcü penceresinin veri kılavuzuna Grupla'yı seçip açarak ve iş parçacıklarını nasıl gruplandırmak istediğinize göre karşılık gelen menü öğesini seçerek yapabilirsiniz.

Kod içinde belirli bir konuma tüm iş parçacıklarını çalıştırmak

Verilen döşemedeki tüm iş parçacıklarını imlecin bulunduğu satıra Geçerli döşemeyi imlece çalıştır'ı kullanarak çalıştıştırabilirsin.

İmleç ile işaretlenmiş yere tüm iş parçacıklarını çalıştırmak

  1. Dondurulmuş iş parçacıkları için kısayol menüsünden Çözme'yi seçin.

  2. Kod Düzenleyicisi'nde, imleci satır 30'a koyun.

  3. Kod düzenleyicisi için kısayol menüsünde Geçerli döşemeyi imlece çalıştır'ı seçin.

    Önceden satır 21'deki engelde engellenmiş 24 iş parçacığı satır 32'ye ilerledi.Bu GPU iş parçacıkları penceresinde gösterilir.

Ayrıca bkz.

Görevler

Nasıl yapılır: gpu iş parçacığı penceresini kullanma

Nasıl yapılır: paralel Gözcü penceresini kullanma

Kavramlar

C++ amp genel bakış

Diğer Kaynaklar

gpu kod hata ayıklama

Eşzamanlılıkk görselleştiricisi ile C++ AMP kodu analiz etmek