我一直在寻找最快的方法来处理popcount大数据.我遇到了一个很奇怪的效果:改变从循环变量unsigned至uint64_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++编写的计算代码,考虑到高性能和低内存开销.它大多使用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已经是容器不可知),并且总是需要当前索引.您需要键入的所有其他代码(迭代器本身和索引)只会使问题复杂化并模糊底层代码的简单性.
应该使用C99中的数组索引的类型?它必须适用于LP32,ILP32,ILP64,LP64,LLP64等.它不一定是C89类型.
我找到了5位候选人:
size_tptrdiff_tintptr_t/uintptr_tint_fast*_t/uint_fast*_tint_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提供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)
但这也无助于可读性,当然,它与原始片段没有相同的语义.
所以,我的问题是:只给出索引限制的类型,推断循环索引变量类型的最佳方法是什么.
这是一个最佳实践问题.我正在制作一个阵列
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在这里只是我实际要做的事情的持有者.