当前位置: 首页 > 知识库问答 >
问题:

求和问题的并行实现返回意想不到的结果

艾焕
2023-03-14

我想尝试一种不同的方法,所以我混合了合并排序算法的并行实现,这是一种分治方法,与典型的数字相加方法。

代码如下:

class SequentialSum {
    public static long sum(int[] numbers, int low, int high) {
        long total = 0;
        for (int i = low; i <= high; i++) total += numbers[i];
        return total;
    }
}

class ParallelSum {

    private static final AtomicLong finalSum = new AtomicLong(0);

    public static void parallelSum(int[] numbers, int low, int high, int threads) {

        if (threads <= 1) finalSum.addAndGet(SequentialSum.sum(numbers, low, high));

        int middle = (low + high) / 2;
        Thread left = new Thread(() -> parallelSum(numbers, low, middle, threads / 2));
        Thread right = new Thread(() -> parallelSum(numbers, middle + 1, high, threads / 2));

        left.start();
        right.start();
    }

    public static long getOutput() {
        return finalSum.get();
    }
}

public class _3_ParallelSummation {

    private static final int NUM_OF_THREADS = Runtime.getRuntime().availableProcessors();
    private static final Random random = new Random();
    private static final int ARRAY_LENGTH = 100_000_000;

    public static void main(String[] args) throws InterruptedException {

        int[] numbers = new int[ARRAY_LENGTH];
        for (int i = 0; i < ARRAY_LENGTH; i++) numbers[i] = random.nextInt(10);


        long t1 = System.currentTimeMillis();
        long sum = SequentialSum.sum(numbers, 0, ARRAY_LENGTH - 1);
        long t2 = System.currentTimeMillis();
        System.out.printf("Sum is: %d, completed in %d ms\n", sum, t2 - t1);

        t1 = System.currentTimeMillis();
        ParallelSum.parallelSum(numbers, 0, ARRAY_LENGTH - 1, NUM_OF_THREADS);
        t2 = System.currentTimeMillis();
        Thread.sleep(1000);
        System.out.printf("Sum is: %d, completed in %d ms\n", ParallelSum.getOutput(), t2 - t1);
    }
}

我得到了意想不到的结果:

Sum is: 449963052, completed in 56 ms
Sum is: 3950670566, completed in 3 ms
[28.597s][warning][os,thread] Failed to start thread - _beginthreadex failed (EACCES) for attributes: stacksize: default, flags: CREATE_SUSPENDED STACK_SIZE_PARAM_IS.
[28.598s][warning][os,thread] Failed to start thread - _beginthreadex failed (EACCES) for attributes: stacksize: default, flags: CREATE_SUSPENDED STACK_SIZE_PARAM_IS.
[28.598s][warning][os,thread] Failed to start thread - _beginthreadex failed (EACCES) for attributes: stacksize: default, flags: CREATE_SUSPENDED STACK_SIZE_PARAM_IS.
[28.601s][warning][os,thread] Failed to start thread - _beginthreadex failed (EACCES) for attributes: stacksize: default, flags: CREATE_SUSPENDED STACK_SIZE_PARAM_IS.

我在代码中犯了什么错误?还是我的思维方式不对?

共有1个答案

仰钧
2023-03-14

合并排序中缺少else块

if (threads <= 1) { 
            finalSum.addAndGet(SequentialSum.sum(numbers, low, high));
        }else {
        int middle = (low + high) / 2;
        Thread left = new Thread(() -> parallelSum(numbers, low, middle, threads / 2));
        Thread right = new Thread(() -> parallelSum(numbers, middle + 1, high, threads / 2));
        left.start();
        right.start();
}

添加else块将修复代码。

您还可以使用join()删除固定的睡眠时间

left.join();
right.join();
 类似资料:
  • 我需要从类B中的方法C返回一个值。 我希望我的代码像这样处理:1 - 2 - 3 - 4 - 5 但它的处理方式是:1-4-5-2-3 (如您所见,我在代码中添加了一些日志。) 我已经处理这个问题一个多星期了,但我找不到问题。 我在这个问题中删除了一些无用的代码。 问题是什么?我如何解决这个问题? 我重写了这篇文章,因为有人说我把代码缩短得太多了。 希望足够了! 提前谢谢你!

  • 我需要刷新令牌,但HttpErrorResponse不会返回请求的结果。 收到http://127.0.0.1:8000/api/pdv返回响应:{“令牌错误”:“令牌已过期”} 但是,当我的令牌过期时,我会收到(跨源请求被阻止)。就这个案子。 这是我的配置 配置/cors我用的是barryvdh/laravel-cors 中间件组 我试图得到回应(console.log(error.error)

  • 我使用了以下映射:我修改了英语分析器来使用ngram分析器,如下所示,这样我应该能够在以下情况下进行搜索:1]部分搜索和特殊字符搜索2]以获得语言分析器的优势 将我的数据索引如下:

  • 问题内容: 假设我的数据库方案如下: 如果我运行第一个查询来获取所有产品及其用户(如果有的话),则会得到以下信息: 对我来说看上去很好。现在,如果我想做同样的事情,除了我希望每行有一个产品,并使用级联的用户名(如果有任何用户,否则为NULL): 如果没有产品的用户,即使存在 LEFT JOIN ,GROUP_CONCAT也会阻止mysql为该产品生产线。 这是预期的MySQL行为吗? 有什么办法可

  • 本文向大家介绍iOS10实现推送功能时的注意点和问题总结,包括了iOS10实现推送功能时的注意点和问题总结的使用技巧和注意事项,需要的朋友参考一下 1、在项目 target 中,打开Capabilitie —> Push Notifications,并会自动在项目中生成 .entitlement 文件。(很多同学升级后,获取不到 deviceToken,大概率是由于没开这个选项) Capabili

  • 问题内容: 我有一个包含一个结构的结构,并且我想序列化为一个对象: 如何最好地将Packet序列化为,以及如何最好地对其进行反序列化? 使用 只给了我名称和数据的指针。我正在探索,但是随后我必须将Packet作为对象,并且我希望将其保留为结构。 干杯 尼克 问题答案: 没有真正得到任何反馈,这是我最终得到的解决方案: 我的结构的制造和功能 更改为,以便在32位和64位平台上具有相同的大小 具有一个