C语言 如何高效地使用Pthread生成和处理多线程组合?

4sup72z8  于 2023-10-16  发布在  其他
关注(0)|答案(1)|浏览(109)

我有2个文件,1个包含所有16位数字,另一个包含144个自定义8位数字。
我的目标是生成这样的组合[16-bit][16-bit][8-bit],总共40位,然后组合将是数十亿到数万亿。我想使用pThread将它们分发到多个线程。
下面是我目前为止的代码
从文本文件中读取数字到3个数组中:

FILE *fil = fopen("pair.txt","r");
    FILE *fd = fopen("pair2.txt","r");
    size_t aln = 32768;
    size_t aln1 = 144;
    size_t numb[aln];
    size_t numb1[aln];
    size_t lump[aln1];
    int count = 0;
    char line[32768];
    while(fgets(line, sizeof(line), fil) != NULL)
    {
        size_t num;
        if(sscanf(line, "%zu", &num) == 1)
        {
            if(count < aln)
            {
                numb[count] = num;
                numb1[count] = num;
                count++;
            }
        }
    }
    count = 0;
    char line1[144];
    while(fgets(line1, sizeof(line1), fd) != NULL)
    {
        size_t num;
        if(sscanf(line1, "%zu", &num) == 1)
        {
            if(count < aln1)
            {
                lump[count] = num;
                count++;
            }
        }
    }

生成和分发组合:

thread ts[NUM_WORKERS];

    for (size_t i = 0; i < NUM_WORKERS; i++)
    {
        size_t x, y, end, d;
        //get value from arrays
        for(size_t a = 0; a < sizeof(numb); a++)
        {
            x = numb[a];
            for(size_t b = 0; b < sizeof(numb1); b++)
            {
                y = numb1[b];
                for(size_t c = 0; c < sizeof(numb2); c++)
                {
                    end = numb2[c];
                    for(size_t f = 0; f < sizeof(lump); f++)
                    {
                        d = lump[f];
                        ts[i] = spawn_worker(x, y, end, d);
                    }
                }
            }
        }
    }
    for (size_t i = 0; i < NUM_WORKERS; i++)
        join_thread(ts[i]);

下面是Spawn_worker函数:

static thread spawn_worker(size_t x, size_t y, size_t end, size_t d)
{
    struct info *info = (struct info *)malloc(sizeof(struct info));
    assert(info != NULL);
    //info->n = n;
    info->x = x;
    info->y = y;
    info->end = end;
    info->d = d;
    thread t = spawn_thread(worker, info);
    if (t == (thread)NULL)
    {
        fprintf(stderr, "error: failed to spawn thread");
        exit(EXIT_FAILURE);
    }
    return t;
}

worker函数:

static void *worker(void *arg)
{
    struct info *info = (struct info *)arg;
    size_t n = info->n;
    size_t x = info->x;
    size_t y = info->y;
    size_t end = info->end;
    size_t d = info->d;
    free(info);
    uint160_t target;
    memcpy(&target, &targ, sizeof(target));
   // COMPUTE WORK:
    if (stop)
        return NULL;
    uint160_t ad = f(x, y, end, d);
    if (is_equal(n, ad, target))
    {
        size_t w = 80;
        printf("\n");
        uint256_t key0 = gen_priv_key(x, y, end, d);
        for (size_t i = 0; i < sizeof(key0); i++)
            {
               printf("%.2X", key0.i8[i]);
            }
           printf("\n");
        if (!is_equal(w, ad, target))
        {
            stop = true;
            uint256_t key1 = gen_priv_key(x, y, end, d);
            //print private key here
            printf("=====================================================\n");
            for (size_t i = 0; i < sizeof(key1); i++)
            {
               printf("%.2X", key1.i8[i]);
           }
           printf("=======================================================\n");
        }
    }

但我不认为我做得对,我不是一个C大师,但我认为生成所有组合并存储它们,然后将它们分发给线程是最好的方法。我有32个核心,64个线程在一个256 GB RAM+8 TB存储。
请问如何有效地分配这项工作?
请注意,每个组合都是40位,即2个16-bit数字和1个8-bit数字。
示例组合:[34628,37562,4096],所以不要与代替8位数字的4096混淆,它的表示是1000,就像在10中附加了零,因此为什么最后一个数组只有144个值(10到9f)。
我希望这能澄清一点。

tktrz96b

tktrz96b1#

多亏了所有的评论,我现在成功地在每个线程中生成了20亿个组合。下面是我如何修改代码:

FILE *fd = fopen("pair2.txt","r");
    size_t aln = 32768;
    size_t aln1 = 144;  
    int count = 0;
    char line1[144];
    while(fgets(line1, 144, fd) != NULL)
    {
        size_t num;
        if(sscanf(line1, "%zu", &num) == 1)
        {
            if(count < aln1)
            {
                lump[count] = num;
                count++;
            }
        }
    }
    size_t bat[65] = {
    32768, 33280, 33792, 34304, 34816, 35328, 35840, 36352, 36864, 37376, 
    37888, 38400, 38912, 39424, 39936, 40448, 40960, 41472, 41984, 42496, 
    43008, 43520, 44032, 44544, 45056, 45568, 46080, 46592, 47104, 47616, 
    48128, 48640, 49152, 49664, 50176, 50688, 51200, 51712, 52224, 52736, 
    53248, 53760, 54272, 54784, 55296, 55808, 56320, 56832, 57344, 57856, 
    58368, 58880, 59392, 59904, 60416, 60928, 61440, 61952, 62464, 62976, 
    63488, 64000, 64512, 65024, 65536};
 if (!stop)
    {
        thread ts[NUM_WORKERS];
        // Start new work:
        for (size_t i = 0; i < NUM_WORKERS; i++)
        {
            ts[i] = spawn_worker(bat[i], bat[i+1],n);           
        }
        for (size_t i = 0; i < NUM_WORKERS; i++)
            join_thread(ts[i]);
            
     }
    printf("|\n");

然后Spawn_workerworker函数:

static thread spawn_worker(size_t x, size_t y, size_t n)
{
    struct info *info = (struct info *)malloc(sizeof(struct info));
    assert(info != NULL);
    info->x = x;
    info->y = y;
    info->n = n;
    thread t = spawn_thread(worker, info);
    if (t == (thread)NULL)
    {
        fprintf(stderr, "error: failed to spawn thread");
        exit(EXIT_FAILURE);
    }
    return t;
}

static void *worker(void *arg)
{
    struct info *info = (struct info *)arg;
    size_t x = info->x;
    size_t y = info->y;
    size_t n = info->n;
    free(info);
    uint160_t target;
    memcpy(&target, &targ, sizeof(target));
   // COMPUTE WORK:
    for(size_t a = x; a <= y; a++)
    {
        if (stop)
            return NULL;
        for(size_t b = 32769; b <= 65536; b++)
        {
            if (stop)
                return NULL;
            for(size_t c = 0; c <= 144; c++)
            {
                if (stop)
                    return NULL;
                size_t lp = lump[c];
                uint160_t ad = f(a, b, lp);
                if (is_equal(n, ad, target))
                {
                    size_t w = 80;
                    printf("\n");
                    uint256_t key0 = gen_priv_key(a, b, lp);
                    for (size_t i = 0; i < sizeof(key0); i++)
                        {
                           printf("%.2X", key0.i8[i]);
                        }
                       printf("\n");
                    if (is_equal(w, ad, target))
                    {
                        stop = true;
                        uint256_t key1 = gen_priv_key(a, b, lp);
                        //print private key here
                        printf("=====================================================\n");
                        for (size_t i = 0; i < sizeof(key1); i++)
                        {
                           printf("%.2X", key1.i8[i]);
                         }
                       printf("=======================================================\n");
                    }
                }
            }
        }
    }

    }

然后我检查了64个工作线程是否正在运行,是的,它们正在运行。注:stop标志用于在任何线程找到解决方案时停止。

相关问题