相关疑难解决方法(0)

用64位替换32位循环计数器会引入疯狂的性能偏差

我一直在寻找最快的方法来处理popcount大数据.我遇到了一个很奇怪的效果:改变从循环变量unsigneduint64_t50%在我的电脑上所做的性能下降.

基准

#include <iostream>
#include <chrono>
#include <x86intrin.h>

int main(int argc, char* argv[]) {

    using namespace std;
    if (argc != 2) {
       cerr << "usage: array_size in MB" << endl;
       return -1;
    }

    uint64_t size = atol(argv[1])<<20;
    uint64_t* buffer = new uint64_t[size/8];
    char* charbuffer = reinterpret_cast<char*>(buffer);
    for (unsigned i=0; i<size; ++i)
        charbuffer[i] = rand()%256;

    uint64_t count,duration;
    chrono::time_point<chrono::system_clock> startP,endP;
    {
        startP = chrono::system_clock::now();
        count = 0;
        for( unsigned k = 0; k < …
Run Code Online (Sandbox Code Playgroud)

c++ performance x86 assembly compiler-optimization

1370
推荐指数
9
解决办法
15万
查看次数

如何处理"签名/未签名的不匹配"警告(C4018)?

我使用大量用C++编写的计算代码,考虑到高性能和低内存开销.它大多使用STL容器vector,并且几乎在每个函数中遍历那些容器.

迭代代码如下所示:

for (int i = 0; i < things.size(); ++i)
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)

但它会产生签名/未签名的不匹配警告(Visual Studio中的C4018).

替换int某种unsigned类型是一个问题,因为我们经常使用OpenMP pragma,它需要计数器int.

我即将压制(数百个)警告,但我担心我错过了一些优雅的解决方案.

在迭代器上.我认为在适当的地方应用迭代器很棒.我正在使用的代码永远不会将随机访问容器更改为list某种东西(因此迭代int i已经是容器不可知),并且总是需要当前索引.您需要键入的所有其他代码(迭代器本身和索引)只会使问题复杂化并模糊底层代码的简单性.

c++ refactoring

71
推荐指数
5
解决办法
9万
查看次数

C中数组索引的正确类型是什么?

应该使用C99中的数组索引的类型?它必须适用于LP32,ILP32,ILP64,LP64,LLP64等.它不一定是C89类型.

我找到了5位候选人:

  • size_t
  • ptrdiff_t
  • intptr_t/uintptr_t
  • int_fast*_t/uint_fast*_t
  • int_least*_t/uint_least*_t

有一个简单的代码可以更好地说明问题.什么是最好的类型i,并j在这两个特定的循环.如果有充分的理由,两种不同的类型也可以.

for (i=0; i<imax; i++) {
        do_something(a[i]);
}
/* jmin can be less than 0 */
for (j=jmin; j<jmax; j++) {
        do_something(a[j]);
}
Run Code Online (Sandbox Code Playgroud)

PS在问题的第一个版本中,我忘记了负面索引.

PPS我不打算编写C99编译器.但是编译器程序员的任何答案对我来说都是非常有价值的.

类似的问题:

c indexing types c99

40
推荐指数
5
解决办法
2万
查看次数

用于循环索引类型演绎的最佳实践

比方说,我有一个c提供size()方法的类型的容器,我想循环遍历这个容器,同时跟踪每个项目的索引:

for (/*TODO*/ i = 0; i < c.size(); i++) {...}
Run Code Online (Sandbox Code Playgroud)

在后C++ 11世界中,自动类型演绎很好地解决了很多问题.我们应该用什么来取代TODO上述?对我来说唯一正确的,无论类型size()是什么,如下:

for (decltype(c.size()) i = 0; i < c.size(); i++) {...}
Run Code Online (Sandbox Code Playgroud)

但这看起来过于冗长,在我看来,这无助于可读性.

另一种解决方案可能是:

for (auto end = c.size(), i = 0; i < end; i++) {...}
Run Code Online (Sandbox Code Playgroud)

但这也无助于可读性,当然,它与原始片段没有相同的语义.

所以,我的问题是:只给出索引限制的类型,推断循环索引变量类型的最佳方法是什么.

c++ c++11 type-deduction

11
推荐指数
1
解决办法
959
查看次数

我应该使用什么类型的索引变量

这是一个最佳实践问题.我正在制作一个阵列

type * x = malloc(size*sizeof(type));
Run Code Online (Sandbox Code Playgroud)

AFAIK sizeof给出size_t的返回值.这是否意味着我应该使用size_t来声明或传递大小?另外,当索引数组时,我还应该使用size_t作为索引变量吗?这些最佳做法是什么?这不是他们在学校教的东西,而现在我正在深入了解我想知道的严肃的c ++.

此外,如果有人参考我可以找到这种东西的最佳实践,它会有帮助吗?程序员预订的礼仪.

编辑:malloc应该是cudaHostAlloc,或cudaMalloc,因为我正在开发一个同时在设备和主机上存储数组的类,并同时更新它们.所以malloc在这里只是我实际要做的事情的持有者.

c++ cuda

6
推荐指数
1
解决办法
1716
查看次数