현재 가능한 모든 문자열 조합을 생성하는 ac 프로그램이 있습니다. 순열이 아닌 조합에 유의하십시오. 이것은 프로그램입니다 :
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//Constants
static const char set[] = "abcd";
static const int setSize = sizeof(set) - 1;
void brute(char* temp, int index, int max){
//Declarations
int i;
for(i = 0; i < setSize; i++){
temp[index] = set[i];
if(index == max - 1){
printf("%s\n", temp);
}
else{
brute(temp, index + 1, max);
}
}
}
void length(int max_len){
//Declarations
char* temp = (char *) malloc(max_len + 1);
int i;
//Execute
for(i = 1; i <= max_len; i++){
memset(temp, 0, max_len + 1);
brute(temp, 0, i);
}
free(temp);
}
int main(void){
//Execute
length(2);
getchar();
return 0;
}
조합의 최대 길이를 수정할 수 있습니다. 현재 데모 용으로 2로 설정되어 있습니다. 현재 구성되어있는 경우 프로그램은
a, b, c, d, aa, ab, ac, ad, ba, bb, bc, bd, ca, cb, cc...
이 프로그램을 cuda로 번역했습니다.
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//On-Device Memory
__constant__ char set_d[] = "adcd";
__constant__ int setSize_d = 4;
__device__ void brute(char* temp, int index, int max){
//Declarations
int i;
for(i = 0; i < setSize_d; i++){
temp[index] = set_d[i];
if(index == max - 1){
printf("%s\n", temp);
}
else{
brute(temp, index + 1, max);
}
}
}
__global__ void length_d(int max_len){
//Declarations
char* temp = (char *) malloc(max_len + 1);
int i;
//Execute
for(i = 1; i <= max_len; i++){
memset(temp, 0, max_len+1);
brute(temp, 0, i);
}
free(temp);
}
int main()
{
//Execute
cudaSetDevice(0);
//Launch Kernel
length_d<<<1, 1>>>(2);
cudaDeviceSynchronize();
getchar(); //Keep this console open...
return 0;
}
원래 프로그램의 cuda 버전은 기본적으로 c 프로그램의 정확한 복사본입니다 (이 프로그램은 -arch=sm_20
. 따라서 printf
cuda 환경에서 다른 호스트 함수가 작동 한다는 점에 유의하십시오 ).
내 목표는 a-z, A-Z, 0-9, and other characters
최대 길이의 조합을 최대 10 개까지 계산하는 것입니다 . 그렇기 때문에이 프로그램이 내 GPU에서 실행되기를 원합니다. 현재로서는 병렬 처리를 이용하지 않습니다. 이는 분명히 cuda에서 프로그램을 작성하는 전체 목적을 무너 뜨립니다. 그러나 스레드를 특정 인덱스 또는 시작 지점으로 위임하는 것 외에도 프로그램의 재귀 적 특성을 제거하는 방법을 잘 모르겠습니다.
건설적인 의견을 보내 주시면 감사하겠습니다.
또한 연속 컴파일시 가끔 경고 메시지가 나타납니다 (산발적으로 나타남) warning : Stack size for entry function '_Z8length_di' cannot be statically determined
.
나는 아직 문제를 정확히 찾아 내지 못했지만, 내가 할 수 있기 전에 누군가가 원인을 알아낼 경우에 대비해 게시 할 것이라고 생각했습니다. Visual Studio 2012에서 컴파일 중입니다.
참고 : 상당히 흥미 롭습니다. cuda 프로그램이 이제는 콘솔에 대한 출력이 주기적입니다. 즉, 수십 개의 조합을 인쇄하고, 일시 중지하고, 수십 개의 조합을 인쇄하고, 일시 중지하는 등의 작업을 수행합니다. 또한보고 된 GPU 사용량에서도이 동작을 관찰합니다. 주기적으로 5 %에서 100 %로 변동합니다.
나는 이것을 위해 재귀를 사용할 필요가 없다고 생각합니다. (아니요).
printf
커널에서 사용 하는 것은 많은 양의 출력에 문제가 있습니다 . 실제로 그 목적을 위해 설계되지 않았습니다. 그리고 printf
커널에서 GPU가 가질 수있는 속도 이점을 제거합니다. 이와 같은 큰 벡터 공간을 테스트하는 경우 목표는 모든 조합을 인쇄하는 것이 아닙니다. 그것이 당신의 목표 printf
이더라도 커널에서가는 길은 아닙니다.
또 다른 문제는 염두에두고있는 전체 벡터 공간에 대한 스토리지입니다. 각 벡터에 대해 처리하려는 일부 처리가 있고이를 폐기 할 수있는 경우 스토리지는 문제가되지 않습니다. 그러나 k = 62 이상의 가능한 값 (a..z, A..Z, 0..9 등)을 가진 "숫자"(요소)가있는 길이 n = 10의 벡터 공간에 대한 저장 공간은 엄청납니다. k ^ n으로 주어 지므로이 예제에서는 62 ^ 10 개의 다른 벡터가됩니다. 각 숫자를 저장하는 데 1 바이트가 필요한 경우 7 조 기가 바이트 가 넘습니다 . 따라서 이것은 전체 벡터 공간의 저장이 의문의 여지가 없음을 거의 나타냅니다. 어떤 일을하려고하더라도 즉석에서해야합니다.
위의 논의를 감안할 때이 답변 에는 필요한 모든 것이 있어야합니다. 벡터 숫자는로 처리되며 "숫자"(즉, z, A..Z, 0..9 등) unsigned int
간에 원하는 매핑을 만들 수 있습니다 unsigned int
.이 예에서 각 벡터에 대해 수행 된 함수 자릿수 합계가 특정 값과 일치하는지 테스트하고 있었으므로 커널에서 다음 줄을 바꿀 수 있습니다.
if (vec_sum(vec, n) == sum) atomicAdd(count, 1UL);
생성 된 각 벡터에 적용하려는 기능과 처리가 무엇이든. printf
여기에를 넣을 수도 있지만 더 큰 공간의 경우 출력이 조각화되고 불완전합니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다