Qt 线程似乎并没有在内核上平均共享

Posted

技术标签:

【中文标题】Qt 线程似乎并没有在内核上平均共享【英文标题】:Qt threading does not seem to share equally over cores 【发布时间】:2012-03-28 20:07:18 【问题描述】:

我有一个多线程应用程序。但是我注意到,我正在使用 OpenGL,如果没有信号量,这将无法正常工作。它确实做到了。我后来添加了信号量,因为它们应该被使用。

不太好,我现在有一个多线程应用程序,它似乎并没有真正利用 CPU 上的多个线程或内核。

我的负载平衡似乎总是针对单核(4 个),至少相差 40%。

我需要在 Qt 的项目文件中切换触发器,还是我忽略了其他东西?这种行为可能是意料之中的,但如果是这样,澄清一下就好了。

我的平台是 Ubuntu 11.10。

class DrawChunkThread : public QThread

    public:
        DrawChunkThread(World *world, int x, int z);
        void run();
        World *world;
        int x;
        int z;
        static QSemaphore *sem;
    private:
;


QSemaphore *DrawChunkThread::sem = new QSemaphore(1);

DrawChunkThread::DrawChunkThread(World *world, int x, int z) 
    this->world = world;
    this->x = x;
    this->z = z;


void DrawChunkThread::run()

    world->drawChunk(x, z);
    if (world->isInside) 
        world->drawInsideChunk(x, z);
    

【问题讨论】:

有很多因素需要考虑...将是确定哪个线程消耗多少 CPU 的良好开端...尝试分析 你没有说你使用的是哪个平台。无论如何,您可能会发现您的代码正在被序列化,因为您的所有线程可能都在访问单个资源。更糟糕的是,如果您对缓存不友好或过度使用临界区等,您可能会遇到很多问题,这可能会导致线程性能不佳。 您使用哪种语言?是 C++ 吗?请添加语言标签,因为您使用的标签不会为您的问题提供必要的可见性。 OpenGL 无法绘制多线程。您的绘图调用最终将被序列化,以便驱动程序可以一一执行它们。所以在某些时候你最终会遇到一个关键部分。绘制调用的线程提交与线程执行不同。至少这是我的理解:-)。在英特尔网站的某个地方,有一个关于 Civ V 多线程渲染的精彩研讨会。我建议你去追捕它,因为它有很多重要的技巧。抱歉,我现在找不到。 但是使用 OpenGL 向部分添加信号量可以解决这个问题,对吗? 【参考方案1】:

如果您添加的信号量创建了一个太长或太争用(或两者兼有)的关键部分,您将遇到可伸缩性问题,因为并非所有线程都被允许同时执行代码并等待信号量触发上下文切换,这会增加更多开销。

一般来说,包含串行部分的并行应用程序的扩展能力不能超过并行部分除以内核数,根据Amdahl's law。

没有任何具体的代码,我想不出任何其他建议给你。

【讨论】:

临界区仅基于OpenGL输出。所有计算都在这些部分之外,因此应该会产生明显的差异。 @Kaj Toet:您在run 方法中调用的那些函数中还有其他同步吗?你是在做大量的内存操作吗? 不,不是很多内存操作。但是我用每个线程调用同一个对象,所以我想知道是否可能是这样? (当然不是写信给它) 内存带宽可能已饱和。读取频率如何? 有没有办法检查?通过分析即?无论如何,我做了大约 30 (FPS) * 64^2 * 4 * 128bit 的内存读取,可能只是其中的一小部分,所以我应该没问题。

以上是关于Qt 线程似乎并没有在内核上平均共享的主要内容,如果未能解决你的问题,请参考以下文章

为啥线程中的 python asyncio 进程在 Linux 上似乎不稳定?

linux 线程间共享内核栈吗

Openmp 创建了许多线程,但似乎只使用一个内核

SylixOS 下内核线程简介

Qt入门教程QObject篇线程同步

高分求qt写的线程程序,功能每隔一百毫秒查询数据,这个线程在整个程序运行中都一直在运行