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

问题描述 投票:0回答:1

我有 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;
}

还有工作函数:

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 大师,但我认为生成所有组合并存储它们,然后将它们分发到线程是最好的方法。 我在 256GB RAM + 8TB 存储上有 32 个核心、64 个线程。

请问我如何有效地分发这项工作?

请注意每个组合都是 40 位,即 2 个

16-bit
数字和 1 个
8-bit
数字。

示例组合:

[34628,37562,4096]
,所以不要与代替 8 位数字的 4096 混淆,它表示 1000,就像十个附加零一样,因此为什么最后一个数组只有 144 个值(10 到 9f)。

我希望这能澄清一点。

c pthreads combinations permutation
1个回答
0
投票

感谢所有评论,我现在成功地以每个线程 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_worker
worker
功能:

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 标志用于在任何线程找到解决方案时停止。

© www.soinside.com 2019 - 2024. All rights reserved.