【问题标题】:Calculating the throughput in multithreading code计算多线程代码中的吞吐量
【发布时间】:2013-04-23 22:43:13
【问题描述】:

我正在对我的一些客户端代码执行bench marking。现在我正在尝试从我的Multithreading 代码中找出如何计算吞吐量-

我正在使用20 threads 运行我的程序。而且每个线程都会为15 minutes运行,所以所有的20 threads will run for 15 minutes。

下面是我的代码-

public static void main(String[] args) {

try {

        // create thread pool with given size
        ExecutorService service = Executors.newFixedThreadPool(20);

        // queue some tasks
        long startTime = System.currentTimeMillis();
        long endTime = startTime + (15 * 60 * 1000);

        for (int i = 0; i < 20; i++) {
            service.submit(new CassandraReadTask(endTime, columnFamilyList));
        }

        service.shutdown();
        service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
    } catch (Exception e) {
        LOG.warn("Threw a Exception in" + CNAME + e);
    }
}

下面是我实现Runnable interface的类-

class CassandraReadTask implements Runnable {

    public void run() {

        try {

            while (System.currentTimeMillis() <= endTime) {

                double randomNumber = random.nextDouble() * 100.0;

                final String id = generateRandomId(random);

                ICassandraClientDao clientDao = ClientFactory.getInstance().getDao(clientName);

                clientDao.getAttributes(id, columnsList, columnFamily);

            }
        } catch (Exception e) {

            }
    }

}

从上面的代码中,我生成了一些随机 id,我使用它来传递给我的 getAttributes dao 方法。

所以根据我的理解。总计throughput 将是-

total number of request/ total duration the program was run

所以,就我而言,它将是-

total number of id's I have generated/15 minutes

我说的对吗?

【问题讨论】:

    标签: java multithreading throughput


    【解决方案1】:

    只要你正确计算(也许使用共享的AtomicInteger?)所有由不同线程完成的请求,你做的很好。

    但是,我会稍微切换一下您的代码并提交 100,000 个(或其他)随机 ID,然后计算您的线程处理所有这些 ID 所需的时间。这是一个更现实的测试,因为它会更好地显示您的任务提交开销。

    然后你只需输入一个startTimeMillis 并计算从结束到开始的差异,然后计算 100,000(或任何你的数字)除以差异,得到你的平均迭代/毫秒。

    类似:

    long startTimeMillis = System.currentTimeMillis();
    int numIterations = 100000;
    for (int i = 0; i < numIterations; i++) {
        double randomNumber = random.nextDouble() * 100.0;
        final String id = generateRandomId(random);
        service.submit(new CassandraReadTask(id, columnFamilyList));
    }
    service.shutdown();
    service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
    long diff = System.currentTimeMillis() - startTimeMillis;
    System.out.println("Average time per iteration is " + (numIterations / diff));
    

    然后很容易调整线程数和迭代次数来最大化您的吞吐量。

    【讨论】:

    • 这只是衡量创建任务的时间,而不是实际运行它们,对吧?
    • 是的,我也是这么想的。纠正我格雷,如果我错了。
    • 哎呀。对。我忘了把shutdown() 和awaitTermination(...) 抄下来。谢谢@RalfH。
    • 是的,我是用AtomicInteger来统计的。
    【解决方案2】:

    这似乎是正确的,但你怎么数?您可以使用 Callables 而不是 Runnables 来返回生成的 ID 数量。然后你会在关闭 Executor 后得到你所有的 Futures 来总结它。

    【讨论】:

    • 我生成的 id 是 String id,所以它看起来像 1 或 100 或 2000。所以每次它生成任何东西时,我都会将静态计数器增加1。在上面的示例中,我没有显示计数器的代码。但我就是这样做的。然后我可以使用该计数器来计算吞吐量。听起来对吗?
    • 好的,如果你有一些地方可以计算,那么你不需要使用期货。但是该计数器必须是线程安全的,这意味着另一个同步点,因此吞吐量比不计数的要少。更好地使用 Gray 的方法并提交已知数量的作业并花费它们的执行时间。
    • 您能提供一个完整的工作示例吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-25
    • 2012-11-22
    • 2020-07-19
    • 2014-07-01
    • 2016-10-25
    • 1970-01-01
    相关资源
    最近更新 更多