2016-08-05 37 views
-2

Ich habe die folgende Struktur in einem Code und es wurde viele Male verwendet. Um die Lesbarkeit des Codes zu verbessern und die Anzahl der Zeilen zu verringern, muss ich stattdessen ein Makro verwenden. Der Teil, den ich freue mich auf ein Makro für sie zu schreiben ist wie folgt:Schreiben eines C-Makros zur Verwendung in einem CUDA-Kernel

#define _UNROLL_FACTOR_volIntGrad 32 
    int jj = 0; 
    for (; jj < (ngbSize - 32); jj += 32) { 
     int j = offset + jj; 
#pragma unroll 
     for (int k = 0; k < 32; k++){ 
     ... 
     arbitrary calculation 1 (depends on k) 
     ... 
     } 
     ... 
     arbitrary calculation 2 
     ... 
    } 

    for (; jj < (ngbSize - (_UNROLL_FACTOR_volIntGrad/2)); jj+= (_UNROLL_FACTOR_volIntGrad/2)){ 
     int j = offset + jj; 
#pragma unroll 
     for (int k = 0; k < 16; k++){ 
     ... 
     arbitrary calculation 1 (depends on k) 
     ... 
     } 
     ... 
     arbitrary calculation 2 
     ... 
    } 

    for (; jj < (ngbSize - (_UNROLL_FACTOR_volIntGrad/4)); jj+= (_UNROLL_FACTOR_volIntGrad/4)){ 
     int j = offset + jj; 
#pragma unroll 
     for (int k = 0; k < 8; k++){ 
     ... 
     arbitrary calculation 1 (depends on k) 
     ... 
     } 
     ... 
     arbitrary calculation 2 
     ... 
    } 

    for (; jj < (ngbSize - (_UNROLL_FACTOR_volIntGrad/8)); jj+= (_UNROLL_FACTOR_volIntGrad/8)){ 
     int j = offset + jj; 

#pragma unroll 
     for (int k = 0; k < 4; k++){ 
     ... 
     arbitrary calculation 1 (depends on k) 
     ... 
     } 
     ... 
     arbitrary calculation 2 
     ... 
    } 

    for (; jj < (ngbSize - (_UNROLL_FACTOR_volIntGrad/16)); jj+= (_UNROLL_FACTOR_volIntGrad/16)){ 
     int j = offset + jj; 
#pragma unroll 
     for (int k = 0; k < 2; k++){ 
     ... 
     arbitrary calculation 1 (depends on k) 
     ... 
     } 
     ... 
     arbitrary calculation 2 
     ... 
    } 
    for (; jj < ngbSize; jj++){ 
     int j = offset + jj; 
     ... 
     arbitrary calculation 3 
     ... 
    } 
} 

durch willkürliche Berechnung X, ich eine Reihe von Berechnungen bedeuten, die unabhängig von Makro ist und unterscheidet Funktion für Funktion. Weiß jemand, wie man dieses Makro schreibt, um die Größe der oben genannten Struktur zu verringern? zum Beispiel wie folgt aus:

__MACRO 
    arbitrary calculation 1 
    arbitrary calculation 2 
    arbitrary calculation 3 
__END 
+6

Betrachten Sie eine Funktion vor einem Makro – wasthishelpful

+1

ich Sie schon ein gutes Stück von Tests, die manuell Abrollen (und die entsprechende Erhöhung der Komplexität und Abnahme zu schaffen gemacht anmaßen schreiben in der Lesbarkeit) verursacht einen statistisch signifikanten und lohnenden Leistungsvorteil? – EOF

+0

@EOF Ja genau richtig! Dieser Teil eines GPU-Kerns muss wirklich die Schleifengröße für den Compiler wissen lassen, um das Ausrollen zu ermöglichen, um die Leistung zu verbessern. Aber die Lesbarkeit sinkt :-(. – Siamak

Antwort

1

In C++ ist es meist verpönt Makros für etwas anderes zu benutzen als Wachen und bedingte Kompilierung für Plattform-Abhängigkeiten enthalten. Am besten wäre es, eine statische Konstante zu erstellen, die intern verknüpft ist und einen einzigen Wartungspunkt hat. Sie können dies an den Anfang Ihrer Datei setzen.

Wenn Sie C++ 11 verwenden, können Sie eine constexpr für das, was Sie versuchen, verwenden. Der Compiler wird wissen, dass Ihre Anweisung einen Typ hat und nicht nur eine Textersetzung, was im Wesentlichen C-Style-Makros sind.

Der Zweck eines constexpr ist es, ein unveränderliches Objekt zu erstellen, das zur Kompilierzeit wie eine statische Konstante berechnet werden kann. Aber das Großartige an ihnen ist, dass Sie mit ihnen statische Funktionen erstellen können, was in Ihrem Fall nützlich wäre, wenn Sie Berechnungen durchführen, die von anderen abhängig sind.

Siehe die Nutzung für constexpr hier: When should you use constexpr capability in C++11?

+2

Sie könnten erklären, wie "constexpr" mit dem speziellen Problem des OP helfen soll, sonst sieht das nicht so aus, als ob es die Frage beantwortet. – EOF

+0

@JessicaAboukasm Leider hat das OP seine Meinung geändert, das ist eine C (in der Tat, CUDA) Frage :( – kfsone

+0

@kfsone der CUDA 'nvcc'compiler folgt C++ Regeln und behauptet C++ - Konformität. –