NumPy 的np.argsort能够通过传递参数进行稳定排序kind = 'stable'。
也不np.argsort支持反向(降序)顺序。
如果需要不稳定行为,则可以通过 轻松建模降序desc_ix = np.argsort(a)[::-1]。
我正在寻找高效/简单的解决方案来降序稳定排序 NumPy 的a任何可比较的数组dtype。请参阅我在上一段中对“稳定性”的含义。
对于任何数值的情况,dtype可以通过对数组的否定版本进行排序来轻松完成稳定的降序参数排序:
print(np.argsort(-np.array([1, 2, 2, 3, 3, 3]), kind = 'stable'))
# prints: array([3, 4, 5, 1, 2, 0], dtype=int64)
Run Code Online (Sandbox Code Playgroud)
但我需要支持任何类似的,dtype包括np.str_和np.object_。
只是为了澄清 - 也许对于降序排列的经典含义stable意味着相等的元素是从右到左枚举的。如果是这样,那么在我的问题中,含义stable + descending有所不同 - 元素的相等范围应该从左到右枚举,而彼此之间的相等范围按降序排列。即应该像上面的最后一个代码一样实现相同的行为。也就是说,我想要某种意义上的稳定性,就像 Python 在下一个代码中实现的那样:
print([e[0] for e in sorted(enumerate([1,2,2,3,3,3]), key = lambda e: e[1], reverse = True)])
# …Run Code Online (Sandbox Code Playgroud) 我正在尝试仅使用 NumPy 来实现图像卷积代码,类似于cv2.filter2D(...)的做法。
import numpy as np
import time
# kernal
H = np.array([[0,1,0],[1,-4,1],[0,1,0]])
# image
SEED = 23
img = np.random.RandomState(SEED).randint(10, size=(4, 4))
# shapes
Hi, Wi = img.shape
Hk, Wk = H.shape
hk = Hk//2
wk = Wk//2
# padding
new_img = np.pad(img, (hk, wk), 'constant', constant_values=0)
pHi, pWi = new_img.shape
print('img: ')
print(new_img)
print('kernal: ')
print(H)
print('\n')
# image convolution
##################################################
# Method 1
st = time.time()
out = np.zeros((Hi, Wi))
for i in range(hk, …Run Code Online (Sandbox Code Playgroud) CLang-CL 是 MSVC CL 的直接替代品。
有谁知道如何区分我的代码当前是由 clang-cl 还是 msvc 的 cl 编译的?无需在命令行上传递任何额外定义的宏。
使用
#ifdef _MSC_VER
//.....
#endif
Run Code Online (Sandbox Code Playgroud)
不起作用,两个编译器都定义了_MSC_VER。
此外,在 Linux 上的常规 CLang(Windows 也是如此)中,可以转储clang -dM -E - < /dev/null所有定义的宏。但据我所知, clang-cl 和 msvc-cl 都没有这样的选项来转储所有定义的宏,所以我不知道有什么方法可以查看定义的宏列表中的差异,以便两个编译器找出使用哪个宏来区分这些编译器。
当我阅读本文时,下载最新的MSVS 2022然后安装工具集就足够了C++ Windows XP Support for VS 2017 (v141) tools [Deprecated]。
之后,我在 Visual Studio 项目属性内设置了此工具集。根据链接的文章,编译具有 XP 支持的 C++ 应用程序就足够了。
但是在.exe创建我的文件后,如果我在 XP 64 位 SP2 上运行它,则会显示错误:CompareStringEx在KERNEL32.DLL.
因此,使用这个工具集似乎还不够。还需要其他东西。
/D_USING_V110_SDK71_在其他一些地方,我发现编译时还需要添加定义,/SUBSYSTEM:CONSOLE,5.01链接时还需要添加选项。在我的项目属性中,我也尝试添加这两个选项,但仍然CompareStringEx位于最终应用程序的导入表内。
正如@BenVoigt 所建议的,我确实定义了/DWINVER=0x0502 /D_WIN32_WINNT=0x0502. 还将 C++ 标准设置为/std:c++14(我会设置 C++11,但此 MSVS 版本至少允许仅设置 C++14)。仍然有一些非 XP 符号保留在最终的 EXE 中,例如InitializeSRWLock,它可能由我的代码中的 C++11 的std::mutex使用。
有谁知道编译完全兼容 XP 的应用程序所需的一切吗?
更新。我通过执行上述操作并将 C++ CRT 运行时设置为Multi Threaded …
我创建了一个显示乘法表的程序:
for (int a=1; a<=10; a++)
{
cout << endl;
for (int b=1; b<=10; b++)
{
cout << " [" << a*b <<"] ";
}
}
Run Code Online (Sandbox Code Playgroud)
问题是它显示如下:

我尝试使用 setw() 但它不起作用,因为它将它设置为所有数字,因此它只会使结果间隔更多一点。还有什么我可以尝试的吗?
C++编译器在一定条件下为类添加了隐式默认构造函数、复制构造函数、析构函数、转换运算符、赋值运算符等以及其他隐式方法。
如何以最短的方式禁用/删除所有可能的隐式方法?
我不希望我的类不可复制,我只想禁用这些默认方法,以便编译器抛出编译错误,然后我自己实现它们。我只是想过度控制,这样编译器就不会对我的班级做任何无声的工作。
例如我可以做下一件事情(这只是一个虚拟示例,在现实生活中我可以有任何复杂的类):
class C {
private:
C() = delete;
C(C const & other) = delete;
C & operator = (C const & other) = delete;
};
Run Code Online (Sandbox Code Playgroud)
但这是很长的路要走,我也可以忘记删除一些方法签名,我需要删除所有方法。以便我自己从头开始重新实现所有方法。
而且我需要查看其他代码需要/使用且我尚未实现的所有方法的错误,而不是编译器为我默默地实现这些方法。
此外,如果我像上面的示例那样删除默认方法,我如何确定没有其他静默创建的方法?在线是否有 100% 由编译器静默创建的所有标准方法的列表?
我想std::atomic有时可以取代std::mutex. 但是使用 atomic 而不是 mutex 总是安全的吗?示例代码:
std::atomic_flag f, ready; // shared
// ..... Thread 1 (and others) ....
while (true) {
// ... Do some stuff in the beginning ...
while (f.test_and_set()); // spin, acquire system lock
if (ready.test()) {
UseSystem(); // .... use our system for 50-200 nanoseconds ....
}
f.clear(); // release lock
// ... Do some stuff at the end ...
}
// ...... Thread 2 .....
while (true) {
// ... Do …Run Code Online (Sandbox Code Playgroud) 想象一下下面的代码:
for (int i = 0; i < 8; ++i) {
// ... some code
}
Run Code Online (Sandbox Code Playgroud)
我希望这个循环在 MSVC 中展开。在 CLang 中我可以添加#pragma unrollbefore 循环。但是在 MSVC 中如何做同样的事情呢?
我知道无论如何编译器通常会为我展开这个循环,即使没有任何编译指示。但我想真正确定这一点,我想总是展开它。
当然,强制展开的一种方法是使用传入函子的模板化展开函数的递归调用,如以下代码所示:
template <int N, int I = 0, typename F>
inline void Unroll(F const & f) {
if constexpr(I < N) {
f.template operator() <I> ();
Unroll<N, I + 1>(f);
}
}
void f_maybe_not_unrolled() {
int volatile x = 0;
for (int i = 0; i < 8; ++i)
x = …Run Code Online (Sandbox Code Playgroud) std C++ 库中有这样的东西吗?:
template <typename T>
struct TypeHolder { using type = T; };
Run Code Online (Sandbox Code Playgroud)
即仅用于传递类型并存储它的特殊结构。这个想法是我想通过值在函数内部传递它,例如:
void f(auto th) { typename decltype(th)::type val{}; }
void h() {
auto g = [](auto th){ typename decltype(th)::type val{}; };
f(TypeHolder<int>());
g(TypeHolder<int>());
}
Run Code Online (Sandbox Code Playgroud)
因为我可以传递一个类型,template <typename T>但现在我想通过值作为自动函数和/或非模板化 lambda 的参数之一传递它。
存在std::integral_constant可以有点用于类型保持,但它不适合我,因为我不想提供我的类型的值和/或实例化值。不仅如此,我还有非结构类型,因此我无法在 std::integral_constant 中提供它的值。
当然我可以TypeHolder在代码中使用上面提到的模板化结构,但我正在寻找基于标准库的解决方案(如果存在),而不是重新发明轮子。
C++ 自旋锁可以使用std::atomic_flag轻松实现,它可以粗略地编码(没有特殊功能),如下所示:
std::atomic_flag f = ATOMIC_FLAG_INIT;
while (f.test_and_set(std::memory_order_acquire)); // Acquire lock
// Here do some lock-protected work .....
f.clear(std::memory_order_release); // Release lock
Run Code Online (Sandbox Code Playgroud)
另外,正如人们在 uops.info(此处的屏幕)上看到的那样,XCHG 可能会占用30相当流行的 Skylake 上的 CPU 周期。这是相当慢的。
通过这样的程序可以测量自旋锁的整体速度。
是否可以在没有 XCHG 的情况下实现自旋锁定?主要关心的是速度,而不仅仅是使用另一条指令。
最快的自旋锁是什么?是否可以将其改为 10 个周期而不是 30 个?还有5个周期?也许是一些平均运行速度很快的概率自旋锁?
它应该以严格的方式实施,这意味着在 100% 的情况下它可以正确保护代码和数据。如果它是概率性的,那么它应该运行可能的时间,但每次运行后仍能 100% 正确地保护。
对我来说,这种自旋锁的主要目的是保护多个线程内非常小的操作,这些操作运行十几个或两个周期,因此 30 个周期的延迟太大了。当然可以说我可以使用原子或其他无锁技术来实现所有操作。但这种技术并不适用于所有情况,并且还需要花费大量工作才能在许多类和方法的庞大代码库中严格实现。因此,还需要一些通用的东西,比如常规的自旋锁。
c++ ×8
visual-c++ ×3
atomic ×2
clang ×2
numpy ×2
python ×2
arrays ×1
clang++ ×1
clang-cl ×1
class ×1
convolution ×1
default ×1
methods ×1
mutex ×1
performance ×1
sorting ×1
spinlock ×1
stable-sort ×1
types ×1
windows-xp ×1
x86-64 ×1