我需要帮助。我开始使用CUDA(2.3 / 3.0beta)编写一个常见的暴力破解者/密码猜测器。 我尝试了不同的方法来生成定义的ASCII字符集的所有可能的纯文本“候选”。
在这个示例代码中,我想生成所有74 ^ 4种可能的组合(并将结果输出回host / stdout)。
$ ./combinations
Total number of combinations : 29986576
Maximum output length : 4
ASCII charset length : 74
ASCII charset : 0x30 - 0x7a
"0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxy"
CUDA代码(用2.3和3.0b编译 - sm_10) - combinaions.cu:
#include <stdio.h>
#include <cuda.h>
__device__ uchar4 charset_global = {0x30, 0x30, 0x30, 0x30};
__shared__ __device__ uchar4 charset[128];
__global__ void combo_kernel(uchar4 * result_d, unsigned int N)
{
int totalThreads = blockDim.x * gridDim.x ;
int tasksPerThread = (N % totalThreads) == 0 ? N / totalThreads : N/totalThreads + 1;
int myThreadIdx = blockIdx.x * blockDim.x + threadIdx.x ;
int endIdx = myThreadIdx + totalThreads * tasksPerThread ;
if( endIdx > N) endIdx = N;
const unsigned int m = 74 + 0x30;
for(int idx = myThreadIdx ; idx < endIdx ; idx += totalThreads) {
charset[threadIdx.x].x = charset_global.x;
charset[threadIdx.x].y = charset_global.y;
charset[threadIdx.x].z = charset_global.z;
charset[threadIdx.x].w = charset_global.w;
__threadfence();
if(charset[threadIdx.x].x < m) {
charset[threadIdx.x].x++;
} else if(charset[threadIdx.x].y < m) {
charset[threadIdx.x].x = 0x30; // = 0
charset[threadIdx.x].y++;
} else if(charset[threadIdx.x].z < m) {
charset[threadIdx.x].y = 0x30; // = 0
charset[threadIdx.x].z++;
} else if(charset[threadIdx.x].w < m) {
charset[threadIdx.x].z = 0x30;
charset[threadIdx.x].w++;; // = 0
}
charset_global.x = charset[threadIdx.x].x;
charset_global.y = charset[threadIdx.x].y;
charset_global.z = charset[threadIdx.x].z;
charset_global.w = charset[threadIdx.x].w;
result_d[idx].x = charset_global.x;
result_d[idx].y = charset_global.y;
result_d[idx].z = charset_global.z;
result_d[idx].w = charset_global.w;
}
}
#define BLOCKS 65535
#define THREADS 128
int main(int argc, char **argv)
{
const int ascii_chars = 74;
const int max_len = 4;
const unsigned int N = pow((float)ascii_chars, max_len);
size_t size = N * sizeof(uchar4);
uchar4 *result_d, *result_h;
result_h = (uchar4 *)malloc(size );
cudaMalloc((void **)&result_d, size );
cudaMemset(result_d, 0, size);
printf("Total number of combinations\t: %d\n\n", N);
printf("Maximum output length\t: %d\n", max_len);
printf("ASCII charset length\t: %d\n\n", ascii_chars);
printf("ASCII charset\t: 0x30 - 0x%02x\n ", 0x30 + ascii_chars);
for(int i=0; i < ascii_chars; i++)
printf("%c",i + 0x30);
printf("\n\n");
combo_kernel <<< BLOCKS, THREADS >>> (result_d, N);
cudaThreadSynchronize();
printf("CUDA kernel done\n");
printf("hit key to continue...\n");
getchar();
cudaMemcpy(result_h, result_d, size, cudaMemcpyDeviceToHost);
for (unsigned int i=0; i<N; i++)
printf("result[%06u]\t%c%c%c%c\n",i, result_h[i].x, result_h[i].y, result_h[i].z, result_h[i].w);
free(result_h);
cudaFree(result_d);
}
代码应该编译没有任何问题,但输出不是我所期望的。
在仿真模式下:
CUDA kernel done hit
key to continue...
result[000000] 1000
...
result[000128] 5000
在发布模式下:
CUDA kernel done hit
key to continue...
result[000000] 1000
...
result[012288] 5000
我还在代码的不同行使用了__threadfence()和__syncthreads()也没有成功......
PS。如果可能的话,我想生成内核函数内的所有内容。我还尝试在主机主要功能和memcpy 设备中“预先”生成可能的纯文本候选项,这仅适用于非常有限的字符集大小(因为设备内存有限) )。
关于输出的任何想法,为什么重复(甚至用__threadfence()或__syncthreads())?
快速在CUDA内核中生成纯文本(候选)的任何其他方法:-)(~75 ^ 8)?
迎接jan
答案 0 :(得分:1)
顺便说一下,你的循环绑定过于复杂。您不需要做所有工作来计算endIdx,而是可以执行以下操作,使代码更简单。
for(int idx = myThreadIdx ; idx < N ; idx += totalThreads)
答案 1 :(得分:0)
让我们看看:
__syncthreads()
就足够了,因为您对写入全局内存不感兴趣(稍后会详细介绍)if
语句未正确重置循环迭代器:
z < m
中,x == m
和y == m
都必须设置为0。charset
中写入一组4个字符,但每个线程写入相同的4个值。没有线程做任何独立的工作。__threadfence
仅适用于当前在设备上执行的块,这些块可以是应该为内核调用运行的所有块的子集。因此它不能用作同步原语。计算每个线程的x,y,z和w的初始值可能更容易。然后每个线程可以从其初始值开始循环,直到它执行tasksPerThread迭代。将值写出来可能会比现在更多或更少。
编辑:这是一个简单的测试程序,用于演示循环迭代中的逻辑错误:
int m = 2;
int x = 0, y = 0, z = 0, w = 0;
for (int i = 0; i < m * m * m * m; i++)
{
printf("x: %d y: %d z: %d w: %d\n", x, y, z, w);
if(x < m) {
x++;
} else if(y < m) {
x = 0; // = 0
y++;
} else if(z < m) {
y = 0; // = 0
z++;
} else if(w < m) {
z = 0;
w++;; // = 0
}
}
其输出是:
x: 0 y: 0 z: 0 w: 0
x: 1 y: 0 z: 0 w: 0
x: 2 y: 0 z: 0 w: 0
x: 0 y: 1 z: 0 w: 0
x: 1 y: 1 z: 0 w: 0
x: 2 y: 1 z: 0 w: 0
x: 0 y: 2 z: 0 w: 0
x: 1 y: 2 z: 0 w: 0
x: 2 y: 2 z: 0 w: 0
x: 2 y: 0 z: 1 w: 0
x: 0 y: 1 z: 1 w: 0
x: 1 y: 1 z: 1 w: 0
x: 2 y: 1 z: 1 w: 0
x: 0 y: 2 z: 1 w: 0
x: 1 y: 2 z: 1 w: 0
x: 2 y: 2 z: 1 w: 0